作为来自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 指南和相关的常见问题解答以获取更多信息。此功能的替代方案包括:
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 查询字符串运行脚本一次,不使用它再运行一次。同时运行它们很重要。使用 Apache ab 或类似的东西,甚至更简单,只需打开两个浏览器选项卡。例如:
http://localhost/Script.php?Sleep=10
http://localhost/Script.php
如果存在竞争条件,则脚本的第一个实例的结果将等于脚本的第二个实例的结果。
例如,脚本的第二个实例将执行以下 SQL 查询:
<?php
mysql_query( "SELECT SQL_CALC_FOUND_ROWS `aid` From `access` Limit 1" );
?>
这发生在脚本的第一个实例处于休眠状态时。如果存在竞争条件,当脚本的第一个实例唤醒时,它执行的 FOUND_ROWS( ) 的结果应该是第二个脚本实例执行的 SQL 查询中的行数。
但是当你运行它们时,情况并非如此。脚本的第一个实例返回其 OWN 查询的行数,即:
<?php
mysql_query( "SELECT SQL_CALC_FOUND_ROWS `bid` From `blocks` Limit 1" );
?>
所以事实证明不存在竞争条件,并且几乎不需要为解决这个“问题”而提出的每个解决方案。
祝你好运,