現在の位置: ホーム> 最新記事一覧> fetch_*の複数の呼び出しは、結果を「食べた」ようにします

fetch_*の複数の呼び出しは、結果を「食べた」ようにします

M66 2025-05-18

MySQLデータベースを使用して開発する場合、 MySQLI_Resultは一般的に使用されるクラスで、クエリ結果のカプセル化を提供し、開発者が一連のFETCH_*メソッドを介して結果のデータを抽出できるようにします。ただし、これらの方法を使用すると、多くの開発者が問題に遭遇します。FETCH_ *メソッドに複数の呼び出しの後、クエリの結果は「消える」ようで、再びアクセスできません。どうしたの?もっと深く見てみましょう。

1。mysqli_resultの基本概念

MySQLクエリが実行された後、返された結果セットがMySQLI_RESULTオブジェクトにカプセル化されます。 PHPでは、次のようなさまざまなFETCH_*メソッドを呼び出すことで、データラインごとに読み取ることができます。

  • fetch_assoc() :結果行を連想配列で返します。

  • fetch_row() :結果行をアレイのインデックス作成方法で返します。

  • fetch_object() :結果行をオブジェクトとして返します。

例えば:

 $conn = new mysqli("localhost", "user", "password", "database");
$query = "SELECT * FROM users";
$result = $conn->query($query);

この時点で、 $ resultオブジェクトはmysqli_resultであり、上記のfetch_*メソッドを呼び出すために使用できます。

2。fetch_ *を複数回呼び出すと、結果が「消える」と設定されるのはなぜですか?

MySQLI_RESULTオブジェクトがFETCH_*メソッドを呼び出すと、実際にはデータラインでデータを読み取ります。 fetch_*メソッドを呼び出すと、結果セットへのポインターが前進します。これは、 fetch_*が呼び出されるたびに、データの行が消費され、ポインターの位置が更新されることを意味します。 fetch_*メソッドを複数回呼び出すと、読み取るデータがなくなるまで行ごとに読み取ります。

例えば:

 while ($row = $result->fetch_assoc()) {
    // データの処理
}

while ($row = $result->fetch_assoc()) {
    // ここではデータは取得されません,前のクエリが結果セットを完全に消費したため
}

上記のように、最初のループはすべてのデータを読み取り、結果セット全体を消費します。 2番目のループが再びデータを取得しようとすると、結果セットは「食べられる」ため、データを取得できません。

3.この状況を避ける方法は?

これを避けるために、次の方法をとることができます。

3.1 mysqli_data_seek()メソッドを使用します

結果セットを反転する必要がある場合は、 MySQLI_Data_Seek()メソッドを使用してデータポインターをリセットできます。例えば:

 $result = $conn->query("SELECT * FROM users");

while ($row = $result->fetch_assoc()) {
    // 初めてデータを読んでください
}

// リセット結果セットポインター
$result->data_seek(0);

while ($row = $result->fetch_assoc()) {
    // 二度目のデータを読み取ります
}

data_seek(0)を呼び出すと、データポインターを結果セットの先頭に戻し、データを再度読み取ることができます。

3.2 mysqli_fetch_all()メソッドの使用

すべてのデータを一度に取得する場合は、 mysqli_fetch_all()メソッドを使用できます。これにより、すべてのデータがfetch_*のように行ごとに読み取られることなく、すべてのデータを配列に抽出できます。例えば:

 $result = $conn->query("SELECT * FROM users");
$rows = $result->fetch_all(MYSQLI_ASSOC);

// 複数回使用できます $rows 配列のデータ
foreach ($rows as $row) {
    // データの処理
}

このアプローチは、結果セットが線ごとに読み取りされ、結果セットが消費される状況を回避し、結果セットデータを複数の場所で使用できるようにします。

3.3ストアクエリはメモリになります

クエリの結果が小さい場合は、データを配列に保存して、配列内のデータを再利用することもできます。例えば:

 $result = $conn->query("SELECT * FROM users");
$data = [];

while ($row = $result->fetch_assoc()) {
    $data[] = $row;
}

// 複数回使用できます $data 配列
foreach ($data as $row) {
    // データの処理
}

この方法は、データベースの繰り返しのクエリも回避し、結果セットが「食べられる」という問題を回避します。

4。概要

fetch_*メソッドを複数回呼び出すと、結果セットは行ごとに読み取りされ、消費されます。結果セットを複数回トラバースしたい場合、 mysqli_data_seek()を使用して結果セットポインターをリセットするか、 mysqli_fetch_all()を使用してすべてのデータを一度に取得する場合は、良い選択です。これらの方法により、開発中に「結果セットが食べられる」という問題を回避し、データが正しく読み取られるようにすることができます。