MySQLデータベースを使用して開発する場合、 MySQLI_Resultは一般的に使用されるクラスで、クエリ結果のカプセル化を提供し、開発者が一連のFETCH_*メソッドを介して結果のデータを抽出できるようにします。ただし、これらの方法を使用すると、多くの開発者が問題に遭遇します。FETCH_ *メソッドに複数の呼び出しの後、クエリの結果は「消える」ようで、再びアクセスできません。どうしたの?もっと深く見てみましょう。
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_*メソッドを呼び出すために使用できます。
MySQLI_RESULTオブジェクトがFETCH_*メソッドを呼び出すと、実際にはデータラインでデータを読み取ります。 fetch_*メソッドを呼び出すと、結果セットへのポインターが前進します。これは、 fetch_*が呼び出されるたびに、データの行が消費され、ポインターの位置が更新されることを意味します。 fetch_*メソッドを複数回呼び出すと、読み取るデータがなくなるまで行ごとに読み取ります。
例えば:
while ($row = $result->fetch_assoc()) {
// データの処理
}
while ($row = $result->fetch_assoc()) {
// ここではデータは取得されません,前のクエリが結果セットを完全に消費したため
}
上記のように、最初のループはすべてのデータを読み取り、結果セット全体を消費します。 2番目のループが再びデータを取得しようとすると、結果セットは「食べられる」ため、データを取得できません。
これを避けるために、次の方法をとることができます。
結果セットを反転する必要がある場合は、 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)を呼び出すと、データポインターを結果セットの先頭に戻し、データを再度読み取ることができます。
すべてのデータを一度に取得する場合は、 mysqli_fetch_all()メソッドを使用できます。これにより、すべてのデータがfetch_*のように行ごとに読み取られることなく、すべてのデータを配列に抽出できます。例えば:
$result = $conn->query("SELECT * FROM users");
$rows = $result->fetch_all(MYSQLI_ASSOC);
// 複数回使用できます $rows 配列のデータ
foreach ($rows as $row) {
// データの処理
}
このアプローチは、結果セットが線ごとに読み取りされ、結果セットが消費される状況を回避し、結果セットデータを複数の場所で使用できるようにします。
クエリの結果が小さい場合は、データを配列に保存して、配列内のデータを再利用することもできます。例えば:
$result = $conn->query("SELECT * FROM users");
$data = [];
while ($row = $result->fetch_assoc()) {
$data[] = $row;
}
// 複数回使用できます $data 配列
foreach ($data as $row) {
// データの処理
}
この方法は、データベースの繰り返しのクエリも回避し、結果セットが「食べられる」という問題を回避します。
fetch_*メソッドを複数回呼び出すと、結果セットは行ごとに読み取りされ、消費されます。結果セットを複数回トラバースしたい場合、 mysqli_data_seek()を使用して結果セットポインターをリセットするか、 mysqli_fetch_all()を使用してすべてのデータを一度に取得する場合は、良い選択です。これらの方法により、開発中に「結果セットが食べられる」という問題を回避し、データが正しく読み取られるようにすることができます。