「クエリ」機能には次の 2 種類があります。
ここでmysql_query
、完全な結果セットを使用すると、クライアントに保存されます。したがって、一度mysql_query
返されると、サーバー通信は必要ありません。結果セットのサイズを取得して使用できますmysql_seek
。内部的に関数mysql_store_result
が使用され、結果がクライアントでフェッチされている間にサーバーが停止すると、mysql_query
呼び出しは失敗します。ただし、結果セットがクライアントに完全に格納されてmysql_fetch_row
いれば、フェッチ中にサーバーが停止しても失敗しません。
を使用mysql_unbuffered_query
する場合、 への有効なリンクが必要です。これは、結果セットがクライアントに保存されないためです。代わりに、 を呼び出すと各行がフェッチされますmysql_fetch_row
。そのため、リンクが「死ぬ」場合、次の呼び出しmysql_fetch_row
は失敗します。C 関数mysql_use_result
は「バッファなし」呼び出しで使用されます。
これをテストするための単純な PHP スクリプトを作成しました(大きすぎて貼り付けられません)。
mysql_fetch_row
mysql C-Libraryの -function のマニュアルを引用するには:
結果セットの次の行を取得します。mysql_store_result() の後に使用すると、取得する行がそれ以上ない場合、mysql_fetch_row() は NULL を返します。mysql_use_result() の後に使用すると、取得する行がそれ以上ない場合、またはエラーが発生した場合、mysql_fetch_row() は NULL を返します。
これは暗黙的に述べています:
mysql_store_result
(バッファリングされた通常のクエリ) が使用される場合mysql_fetch_row
、フェッチする行がそれ以上ない場合は null のみを返します。
mysql_use_result
(バッファリングされていないクエリ) が使用されている場合、それ以上行がない場合、またはサーバーから次の行をフェッチする際にエラーが発生した場合mysql_fetch_row
は、null を返します。
プラットフォーム固有の動作については言及されていないため、これはすべてのプラットフォームに当てはまると思います。もちろん、これらの関数のソース コードを調べて確認する必要があります。
エラーが発生した場合の動作について: PHP 側mysql_fetch_result
では、バッファリングされていない結果セットのフェッチが失敗した場合 (または行がなくなった場合) に false が返されます。関数はmysql_*
例外をスローしませんが、失敗した場合は警告が発せられます - 私のスクリプトではWarning: mysql_fetch_row(): 8 is not a valid MySQL result resource in ...
. したがって、エラーを確認したい場合は、次のようにする必要があります。
while($row = mysql_fetch_row($result)) {
// do stuff
}
if(mysql_errno($dbhandle) !== 0) {
echo "there was an error: ", mysql_error($dbhandle), PHP_EOL;
}
本当に防御的なコードを書きたい場合は、使用しているクエリ関数に関係なく、それを行う必要があります。
ところで、mysql 接続が で閉じられている場合、この防御コードは機能しません。これはmysql_close
、ハンドルが閉じられ、mysql_errno
false が返されるためです (さらに、警告が発行されます)。