Проблема с итерацией по таблице mysql после одного цикла

#php

#php

Вопрос:

У меня есть 2 таблицы. Первый есть categories , а второй есть items . Мне нужно, чтобы мой скрипт печатал в .txt-файл имя категории и под ним элементы категории с соответствующим ‘category_id’. Мой код использует первый while цикл для перебора категорий, а второй — для перебора элементов. Все работает нормально, пока мы не перейдем ко второму while циклу, потому что тогда значения становятся пустыми.

 while ($row2 = mysqli_fetch_array($query_for_categories)) {
    fwrite($fp, $row2["category_name"].PHP_EOL);
    while ($row = mysqli_fetch_array($query_for_items)) {
        if ($row2['id_category_from_category'] == $row['id_category_from_items']) {
            fwrite($fp, $row["item_name"].PHP_EOL);
        }
    }
}
  

Комментарии:

1. Пожалуйста, отформатируйте свой код, исправьте синтаксические ошибки перед публикацией кода здесь и используйте правильную пунктуацию в вашем вопросе.

2. Я действительно прошу прощения за мою пунктуацию, но я не являюсь носителем английского языка, в будущем буду уделять этому больше внимания

3. В 3-й строке все еще ; не хватает одного и дополнительного } в 5-й строке

4. Какую среду IDE вы используете, чтобы она не выделяла синтаксические ошибки для вас? Пожалуйста, используйте надлежащую среду разработки с программой форматирования кода и анализатором кода, например, VS Code.

5. используя sublime, код был в порядке, но мне пришлось вырезать некоторые части, поэтому я пропустил некоторые ошибки

Ответ №1:

После первой итерации внешнего цикла while вы получите все строки из $query_for_categories . На последующих итерациях внешнего цикла while больше не будет строк для извлечения из этого запроса.

Сначала вы можете извлечь их все в массив

 while ($row = mysqli_fetch_array($query_for_items)) {
    $items[] = $row;
}
  

Затем используйте строки из этого массива вместо цикла выборки while ….

 while ($category = mysqli_fetch_array($query_for_categories)) {
    fwrite($fp, $category["category_name"].PHP_EOL);
    foreach($items as $item) {
        if ($category['id_category_from_category'] == $item['id_category_from_items']) {
            fwrite($fp, $item["item_name"].PHP_EOL);
        }
    }
}
  

Похоже, вы, вероятно, могли бы сделать это с помощью одного запроса, используя соединение. Я бы рекомендовал проверить это вместо того, чтобы делать это таким образом. На основе имен столбцов в вашем коде запрос будет выглядеть примерно так:

 SELECT c.category_name, i.item_name
FROM categories c
  LEFT JOIN items i on c.id_category_from_category = i.id_category_from_items
ORDER BY c.category_name, i.item_name
  

Затем вы могли бы распечатать элементы с категориями в одном цикле следующим образом:

 $previous_category = null;

while ($item = mysqli_fetch_array($query)) {

    // each time category changes, output the new category name
    if ($item['category_name'] != $previous_category) {
        fwrite($fp, $item["category_name"].PHP_EOL);

        // then current category becomes previous category
        $previous_category = $item['category_name'];
    }
    fwrite($fp, $item["item_name"].PHP_EOL);
}
  

Мне интересно, как вы можете определить, какие из строк в файле являются элементами, а какие категориями. Может быть, вам следует вывести какой-то индикатор для этого?

Комментарии:

1. Спасибо, я попробую это немедленно

2. Это сделало свою работу, теперь все работает нормально, я очень благодарен вам за помощь, это также стало для меня огромным уроком. Теперь мой код на 1/2 меньше. Опять же, я очень ценю вашу помощь, и все остальные за то, что указали мне на мои ошибки