Почему return возвращает данные только из первой строки таблицы?

362
07 августа 2017, 11:05

В MySQL есть таблица main:

id | order_id | sub1_arr | sub2_arr | sub3_arr | sub4_arr
 1 |        1 |  3, 6, 7 |          |       70 |         
 2 |        0 |          |          |          |         
 3 |        2 |       33 |25, 83, 9 |          |   39, 10  

Мне нужно вывести значения всех строк из столбцов sub1_arr, sub2_arr, sub3_arr, sub4_arr через запятую.

Пробую вот таким образом:

  $result=mysql_query("SELECT `sub1_arr`,`sub2_arr`,`sub3_arr`,`sub4_arr` FROM `main`");
  while ($arr=mysql_fetch_row($result, MYSQL_ASSOC)) {
    if ($arr['sub1_arr']) {echo $arr['sub1_arr'].','};
    if ($arr['sub2_arr']) {echo $arr['sub2_arr'].','};
    if ($arr['sub3_arr']) {echo $arr['sub3_arr'].','};
    if ($arr['sub4_arr']) {echo $arr['sub4_arr'].','};
  }

То более-менее всё работает как надо, но в конце всегда лишняя запятая. ¯_(ツ)_/¯

Но мне нужно просто вернуть (return) эти значения, а не отображать их (echo). И вот когда возвращаю (return) -- выводятся только записи из первой строки.

Вопрос: как оптимизировать этот запрос и выдачу результата, чтобы получить на выходе: 3, 6, 7, 70, 33, 25, 83, 9, 39, 10

Answer 1

А вы не возвращайте сразу, а накапливайте в строке:

$str = "";
$result=mysql_query("SELECT `sub1_arr`,`sub2_arr`,`sub3_arr`,`sub4_arr` FROM `main`");
while ($arr=mysql_fetch_row($result, MYSQL_ASSOC)) {
    if ($arr['sub1_arr']) {
        $str .= $arr['sub1_arr'].',';
    }
    if ($arr['sub2_arr']) {
        $str .=  $arr['sub2_arr'].',';
    }
    if ($arr['sub3_arr']) {
        $str .= $arr['sub3_arr'].',';
    }
    if ($arr['sub4_arr']) {
        $str .= $arr['sub4_arr'].',';
    }
}
return $str;

Проблемы такого подхода вы заметили сами -- лишняя запятая в конце. Но есть типовой обходной путь для этого:

$str = "";
$is_first = true;
$result=mysql_query("SELECT `sub1_arr`,`sub2_arr`,`sub3_arr`,`sub4_arr` FROM `main`");
while ($arr=mysql_fetch_row($result, MYSQL_ASSOC)) {
    if($is_first)
    {
        $is_first = false;
    }
    else
    {
        $str .= ",";
    }
    if ($arr['sub1_arr']) {
        $str .= $arr['sub1_arr'];
    }
    if ($arr['sub2_arr']) {
        $str .=  $arr['sub2_arr'];
    }
    if ($arr['sub3_arr']) {
        $str .= $arr['sub3_arr'];
    }
    if ($arr['sub4_arr']) {
        $str .= $arr['sub4_arr'];
    }
}
return $str;

Я надеюсь, этот пример вам понятен, потому что правильнее делать накопление в массиве, а не в строке -- а итоговую строку уже собирать через implode (посмотрите комментарий @Mike).

$res = array();
$result=mysql_query("SELECT `sub1_arr`,`sub2_arr`,`sub3_arr`,`sub4_arr` FROM `main`");
while ($arr=mysql_fetch_row($result, MYSQL_ASSOC)) {
    if ($arr['sub1_arr']) {
        $res[] = $arr['sub1_arr'];
    }
    if ($arr['sub2_arr']) {
        $res[] = $arr['sub2_arr'];
    }
    if ($arr['sub3_arr']) {
        $res[] = $arr['sub3_arr'];
    }
    if ($arr['sub4_arr']) {
        $res[] = $arr['sub4_arr'];
    }
}
return implode(", ", $res);

Удобство implode заключается в том, что эта функция не поставит последнюю запятую: ваш вывод будет 3, 6, 7, 70, 33, 25, 83, 9, 39, 10, -- а implode вернёт 3, 6, 7, 70, 33, 25, 83, 9, 39, 10.

Это во-первых. А во-вторых, ещё в школе учат на уроках информатики, что алгоритм должен разделять шаги ввода информации, обработки и вывода. Так вот обработку лучше делать в массиве (данные структурированы), а не в строке, а вывод уже должен быть строкой. Возможно, на таком простом примере как ваш сложно почувствовать эту выгоду, но привыкнув мыслить чётко это потом будет выручать на сложных задачах.

Дополнительно. Склеить в одну строку можно ещё на SQL-сервере. Кроме того, непонятен смысл параметров arr1 - arr4 в таблице mysql, подозреваю, что можно было бы и нормализовать таблицу дальше.

READ ALSO
Генератор Java классов из базы данных Oracle

Генератор Java классов из базы данных Oracle

Есть веб-сервис на JavaЕсть БД Oracle

317
Android Studio - утеряны шаблоны Code Templates

Android Studio - утеряны шаблоны Code Templates

ЗдравствуйтеПодскажите пожалуйста у меня вот такая беда: Установил Android Studio, (при этом переустанавливал и раньше её) и при создании интерфейса...

520
Распознавание жестов android

Распознавание жестов android

Как сделать программу, которая будет распознавать жесты? Пример: я открываю браузер, рисую на экране букву "G" и он мне открывает гуглИли просто...

412
открытие javaFX окна много раз

открытие javaFX окна много раз

при нажатии на кнопку в у меня должно открыться javaFx окноПервый раз открывается отлично, но после открытия окна 2 раз вылетает Exception in thread "main"...

478