fetch_assoc () работает только один раз в цикле - PullRequest
0 голосов
/ 31 октября 2019

Я перебираю 2 таблицы в БД MySQL (используя fetch_assoc ()). Я хотел бы получить текущий идентификатор 1-й таблицы и все идентификаторы второй таблицы на каждой итерации, но я получаю идентификаторы второй таблицы только на первой итерации. Начиная со второй итерации, возвращается только текущий идентификатор 1-й таблицы. Я хотел бы знать, что я делаю неправильно.

Я уже пробовал на Loops и посмотрел подобные вопросы здесь, но ни один действительно не помог.

<?php
$my_sqli = new mysqli('localhost', 'root', '', 'taskpro') or die(mysqli_error($my_sqli));
$data1 = $my_sqli->query("SELECT * FROM task_table") or die($my_sqli->error);
$data2 = $my_sqli->query("SELECT * FROM taskinfo") or die($my_sqli->error);

while ($row = $data1->fetch_assoc()) {
    echo "<br>";
    echo $row['id'];
    echo "<br>";

    while ($row2 = $data2->fetch_assoc()) {
        echo $row2['id'];
    } // end child loop

} // end parent loop

?>

Эторезультат я получаю

1

1234

2

3

4

5

6

7

8

9

10

Ответы [ 3 ]

1 голос
/ 31 октября 2019

В основном вы исчерпали набор результатов второго запроса после завершения первой итерации внешнего запроса.

Есть несколько способов сделать это, вот пара предложений

Сначала вы можете загрузить все результаты второго запроса в массив, а затем просто повторно обрабатывать массив каждый раз вокруг внешнего цикла. Однако функция fetch_all() доступна только в том случае, если у вас установлен собственный драйвер MYSQL. (MYSQLIND)

<?php
$my_sqli = new mysqli('localhost', 'root', '', 'taskpro');
if (!$my_sqli) {
    die('Connect Error: ' . mysqli_connect_errno());
}

$data1 = $my_sqli->query("SELECT * FROM task_table") or die($my_sqli->error);
$data2 = $my_sqli->query("SELECT * FROM taskinfo") or die($my_sqli->error);

$allData2 = data2->fetch_all(MYSQLI_ASSOC);

while ($row = $data1->fetch_assoc()) {
    echo "<br>";
    echo $row['id'];
    echo "<br>";

    foreach ( $allData2 as $row ) {
        echo $row2['id'];
    }
} // end parent loop
?>

Или вы можете использовать функцию mysqli_result::data_seek() для сброса указателя на первую строку результата запроса, например

<?php
$my_sqli = new mysqli('localhost', 'root', '', 'taskpro');
if (!$my_sqli) {
    die('Connect Error: ' . mysqli_connect_errno());
}

$data1 = $my_sqli->query("SELECT * FROM task_table") or die($my_sqli->error);
$data2 = $my_sqli->query("SELECT * FROM taskinfo") or die($my_sqli->error);

while ($row = $data1->fetch_assoc()) {
    echo "<br>";
    echo $row['id'];
    echo "<br>";

    $data2->data_seek(0);   // make sure the pointer is at the beginning before looping
    while ($row2 = $data2->fetch_assoc()) {
        echo $row2['id'];
    } 
}
?>
1 голос
/ 31 октября 2019

Самое простое, что нужно сделать, это прочитать все значения из query2 в массив и затем вывести содержимое массива в цикле:

$my_sqli = new mysqli('localhost', 'root', '', 'taskpro') or die(mysqli_error($my_sqli));
$data1 = $my_sqli->query("SELECT * FROM task_table") or die($my_sqli->error);
$data2 = $my_sqli->query("SELECT * FROM taskinfo") or die($my_sqli->error);

$rows2 = $data2->fetch_all(MYSQLI_ASSOC);
while ($row = $data1->fetch_assoc()) {
    echo "<br>";
    echo $row['id'];
    echo "<br>";

    foreach ($rows2 as $row2) {
        echo $row2['id'];
    } // end child loop

} // end parent loop

Если по какой-то причине вам нужно выполнить итерациюнабор результатов во внешнем цикле, вы можете использовать mysqli_data_seek для сброса указателя:

while ($row = $data1->fetch_assoc()) {
    echo "<br>";
    echo $row['id'];
    echo "<br>";

    while ($row2 = $data2->fetch_assoc()) {
        echo $row2['id'];
    } // end child loop
    // reset $data2 result pointer
    $data2->data_seek(0);

} // end parent loop
0 голосов
/ 31 октября 2019

Прежде всего, вам вообще не нужен цикл while. Это просто сбивает вас с толку. Вы можете просто использовать foreach($data1 as $row). Сказав это, это не решит вашу проблему.

Чтобы решить вашу проблему, позвоните fetch_all(MYSQLI_ASSOC) на результат из query или просто объедините их в цепочку. Будьте осторожны, это работает только со статическими запросами. Если вам нужно использовать переменные в вашем SQL, вы должны использовать подготовленные операторы .

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'root', '', 'taskpro');
$mysqli->set_charset('utf8mb4');

$data1 = $mysqli->query("SELECT * FROM task_table")->fetch_all(MYSQLI_ASSOC);
$data2 = $mysqli->query("SELECT * FROM taskinfo")->fetch_all(MYSQLI_ASSOC);

foreach ($data1 as $row) {
    echo "<br>";
    echo $row['id'];
    echo "<br>";
    foreach ($data2 as $row2) {
        echo $row2['id'];
    } // end child loop
} // end parent loop

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...