为什么mysql_query()使用SELECT语句返回TRUE?

rid*_*rid 9 php mysql

根据mysql_query()我所知道的关于这个函数的手册以及我使用了很多次,它可以返回一个资源,或者FALSE如果查询是一个SELECT.然而,它TRUE不时返回.

怎么会这样?它从未发生过.这是PHP 5.3.2中的错误吗?有人对这个有了解吗?

代码类似于:

if (!$resource = mysql_query($query, $handle)) {
    throw some exception;
}

var_dump($query);
if ($resource === true && strpos($query, 'SELECT') !== false) {
    throw new Exception('mysql_query() returned TRUE for SELECT');
}
Run Code Online (Sandbox Code Playgroud)

复制也很难.它只是偶尔发生.我也注意到这很可能发生在服务器突然中断连接的同时,它应该返回FALSE...

Mel*_*Mel 6

如果webbiedave不在正确的轨道上,那么在php源中只有一个允许这种情况的代码路径:

#if MYSQL_VERSION_ID < 32224
#define PHP_MYSQL_VALID_RESULT(mysql)       \
    (mysql_num_fields(mysql)>0)
#else
#define PHP_MYSQL_VALID_RESULT(mysql)       \
    (mysql_field_count(mysql)>0)
#endif
Run Code Online (Sandbox Code Playgroud)

...

if (!mysql_result) {
    if (PHP_MYSQL_VALID_RESULT(mysql->conn)) { /* query should have returned rows */
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save result set");
        RETURN_FALSE;
    } else {
        RETURN_TRUE; // <<< this case
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为这是一个错误.特别是因为没有真正的方法来验证这一点 - PHP代码中的mysql_num_fields使用的是你没有得到的资源,而不是连接.

虽然在丢失连接时,C版本的mysql_query返回零仍然很奇怪 - 如果你能够,请尝试以下补丁并重新安装mysql扩展:

Index: ext/mysql/php_mysql.c
===================================================================
--- ext/mysql/php_mysql.c       (revision 311719)
+++ ext/mysql/php_mysql.c       (working copy)
@@ -1485,6 +1485,9 @@
                if (PHP_MYSQL_VALID_RESULT(mysql->conn)) { /* query should have returned rows */
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save result set");
                        RETURN_FALSE;
+               } else if( mysql_errno(mysql->conn) != 0 ) {
+                       php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
+                       RETURN_FALSE;
                } else {
                        RETURN_TRUE;
                }
Run Code Online (Sandbox Code Playgroud)