http://php.net/manual/en/function.mysql-fetch-array.phpからの参照として、mysql_fetch_array はフェッチされた行に対応する配列を返し、内部データ ポインターを先に移動します。したがって、mysql_num-rows の前にこれを使用していないことを確認してください。
mysql_unbuffered_query() を使用すると、結果セット内のすべての行が取得されるまで、mysql_num_rows() は正しい値を返しません。
警告 :: mysql_num_rows()
この拡張モジュールは PHP 5.5.0 で非推奨になり、将来的に削除される予定です。代わりに、MySQLi または PDO_MySQL 拡張機能を使用する必要があります。詳細については、MySQL: API ガイドの選択および関連する FAQ も参照してください。この機能の代替手段は次のとおりです。
mysqli_stmt_num_rows()
PDOStatement::rowCount()
SQL_CALC_FOUND_ROWS と FOUND_ROWS( ) を使用すると、MySQL で競合状態が発生することはありません。
プロセスが PHP で何かを共有することは不可能であるため、それらの使用結果は実際には接続セッションごとに異なります。PHP に関する限り、各要求は独自のプロセスに分離されているため、各要求は MySQL への新しい接続を表します。
これをシミュレートするには、次のスクリプトを作成します。
<?php
$Handle = mysql_connect( "localhost" , "root" , "" );
mysql_select_db( "lls" );
if( isset( $_GET[ 'Sleep' ] ) ) {
mysql_query( "SELECT SQL_CALC_FOUND_ROWS `bid` From `blocks` Limit 1" );
} else {
mysql_query( "SELECT SQL_CALC_FOUND_ROWS `aid` From `access` Limit 1" );
}
if( isset( $_GET[ 'Sleep' ] ) ) {
sleep( 10 ); // Simulate another HTTP request coming in.
$Result = mysql_query( "SELECT FOUND_ROWS( )" );
print_r( mysql_fetch_array( $Result ) );
}
mysql_close( );
?>
ご使用の環境に合わせて接続情報とクエリ情報を設定してください。
Sleep クエリ文字列を使用してスクリプトを 1 回実行し、それを使用せずにもう一度スクリプトを実行します。両方を同時に実行することが重要です。Apache ab などを使用するか、さらに簡単に、2 つのブラウザー タブを開くだけです。例えば:
http://localhost/Script.php?Sleep=10
http://localhost/Script.php
競合状態が存在する場合、スクリプトの最初のインスタンスの結果は、スクリプトの 2 番目のインスタンスの結果と等しくなります。
たとえば、スクリプトの 2 番目のインスタンスは、次の SQL クエリを実行します。
<?php
mysql_query( "SELECT SQL_CALC_FOUND_ROWS `aid` From `access` Limit 1" );
?>
これは、スクリプトの最初のインスタンスがスリープしているときに発生します。競合状態が存在する場合、スクリプトの最初のインスタンスが起動したときに、スクリプトが実行する FOUND_ROWS( ) の結果は、スクリプトの 2 番目のインスタンスが実行した SQL クエリの行数になります。
しかし、それらを実行すると、そうではありません。スクリプトの最初のインスタンスは、その OWN クエリの行数を返します。これは次のとおりです。
<?php
mysql_query( "SELECT SQL_CALC_FOUND_ROWS `bid` From `blocks` Limit 1" );
?>
したがって、競合状態が存在しないことが判明し、この「問題」に対処するために提示されたすべてのソリューションはほとんど必要ありません。
幸運を、