Как предотвратить конечную запятую при печати данных с разделителями-запятыми в цикле?

Я пишу php-код, который должен отображать некоторые данные БД в виде группы массивов, разделенных запятыми.

Код выглядит следующим образом:

include('inc_db.php');  
$query = "SELECT * FROM product WHERE p_shop_id=1";
$result = $conn->query($query);
if ($result->num_rows > 0) {
    while($row = $result->fetch_array()) {
        if($result->num_rows == 1)
            echo "[" .$row['p_description'] ."," .$row['p_category'] ."," .$row['p_cost'] ."," .$row['p_stock'] ."]";
        else
            echo "[" .$row['p_description'] ."," .$row['p_category'] ."," .$row['p_cost'] ."," .$row['p_stock'] ."], ";
    }
}
$conn->close();

*включаемая строка - это подключение к БД.

В этой строке:

if($result->num_rows == 1)

Я пытаюсь определить, дошел ли цикл до последней строки результата, чтобы эхо-строка заканчивалась без запятой (как это происходит во фразе else).

Я предполагаю, что неправильно сделал оператор if, потому что когда я запускаю программу, я получаю массив с запятой в конце каждой строки, включая последнюю.

результат:

[Eggs, Food, 20, 20], [Coca Cola, Drinks, 5, 30],

Ожидаемый результат:

 [Eggs, Food, 20, 20], [Coca Cola, Drinks, 5, 30]

(без запятой в конце)

Так как же правильно определить, что цикл while добрался до последней строки?


person Snir    schedule 07.07.2020    source источник
comment
Не изобретайте велосипед и используйте json_encode   -  person u_mulder    schedule 07.07.2020
comment
Создайте переменную $count перед оператором while и установите для нее значение $result-›num_rows. Это будет хранить количество строк, которые у вас есть. Теперь внутри цикла while в конце выполните $count = $count - 1; и в вашем операторе if замените $result-›num_rows == 1 на $count == 1   -  person ximewatch    schedule 07.07.2020
comment
@u_mulder json_encode также будет заключать значения в кавычки.   -  person ximewatch    schedule 07.07.2020
comment
Это похоже на проблему XY. Почему вам нужно, чтобы эта отформатированная строка была отформатирована таким образом? является основным вопросом.   -  person mickmackusa    schedule 07.07.2020
comment
@ximewatch, пожалуйста, не публикуйте ответы в виде комментариев. meta.stackexchange.com/q/230676/352329   -  person mickmackusa    schedule 07.07.2020
comment
@micmackusa Понятно. Спасибо за вашу настойчивость.   -  person axiac    schedule 07.07.2020


Ответы (2)


Вам не нужно считать ряды. Вам также не нужно знать, обрабатываете ли вы последнюю строку.

Я действительно не понимаю, зачем вам нужен этот формат, но вы можете использовать implode() и заключать его в квадратные скобки для краткого хранения данных строки. Затем, когда цикл завершится, вы можете просто снова расставить запятые — это гарантирует, что не будет беспорядка, который нужно убрать.

Этот фрагмент кода преобразует массив массивов в массив строк, заключенных в фигурные скобки и разделенных запятыми, а затем после цикла массив преобразуется в строку с разделителями-запятыми. (Демо)

$result = $conn->query("SELECT p_description, p_category, p_cost, p_stock FROM product WHERE p_shop_id = 1");
$rows = [];
foreach ($result as $row) {
    $rows[] = '[' . implode(', ', $row) . ']';
}
echo implode(', ', $rows);

Или вы можете добавить 0 или 1 запятую перед каждой строкой в ​​скобках: (Условная демонстрация) (Функциональная демонстрация)

foreach ($result as $i => $row) {
    echo ($i ? ', ' : '') . '[' . implode(', ', $row) . ']';
    //echo str_repeat(', ', (bool)$i) . '[' . implode(', ', $row) . ']';
}

Или, если вы предпочитаете функциональные итераторы, вы можете опустить временную переменную $rows и просто использовать array_map(): (Демо)

echo implode(', ', array_map(function($row) {
    return '[' . implode(', ', $row) . ']'; 
}, $result));

Или вы можете использовать array_reduce() и проверить, записаны ли какие-либо данные в переменную $carry при повторении строк. Идея состоит в том, чтобы добавлять запятую только в том случае, если вы не имеете дело с первой итерацией. (Демо)

echo array_reduce($result, function($carry, $row) {
    $carry .= (!$carry ? '' : ', ') . '[' . implode(', ', $row) . ']'; 
    return $carry;
});
person mickmackusa    schedule 07.07.2020

Вы можете объявить переменную, которую вы будете увеличивать в своем цикле, и использовать ее для проверки $result->num_rows, чтобы увидеть, является ли это последней записью.

if ($result->num_rows > 0) {
    $index = 0;
    while($row = $result->fetch_array()) {
            if($result->num_rows == ($index+1)) //Check if it's the last record
                echo "[" .$row['p_description'] ."," .$row['p_category'] ."," .$row['p_cost'] ."," .$row['p_stock'] ."]";
            else
                echo "[" .$row['p_description'] ."," .$row['p_category'] ."," .$row['p_cost'] ."," .$row['p_stock'] ."], ";

          $index++;
            
        }
}
person Clement Sam    schedule 07.07.2020