根据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');
}
重现也很难。它只是偶尔发生。我也注意到这很可能发生在服务器突然中断连接的同时,它应该返回FALSE
...
答案 0 :(得分: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
...
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
}
}
我认为这是一个错误。特别是因为没有真正的方法来验证这一点 - 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;
}
答案 1 :(得分:0)
当你说它“返回TRUE”时,你是如何测试的?你是不是有机会做这样的事,是吗?
$result = mysql_query($sql);
if ($result == TRUE) { /* stuff */ }
如果是这样,请记住,返回的所有非零,非空,非空值将计算为TRUE。您可以使用更严格的方法来验证这一点:
if ($result === TRUE) { /* stuff */ }
不仅评估等价,还评估类型。你在做类似var_export($ result)的事情吗?检查数据类型并验证您实际上是否返回了布尔值TRUE?
答案 2 :(得分:0)
让我们以另一种方式看待这一点,当mysql_query()
返回FALSE
时,这意味着无论何种原因,查询尝试都失败了。这意味着即使在它开始之前,您仍然会查询出错的内容,因此对数据库没有任何影响,或者查询无法达到可以看到数据库的程度。
答案 3 :(得分:0)
您尚未提及数据长度,但您应检查是否超过max_allowed_packet
调用此数据。
当MySQL客户端或mysqld时 服务器收到大于的数据包 max_allowed_packet字节,它发出一个 数据包太大错误并关闭 连接。对于一些客户,你可以 也与MySQL失去联系 服务器在查询错误时如果 通讯包太大了。
[...]
客户端和服务器都有 他们自己的max_allowed_packet变量, 所以如果你想处理大包, 你必须增加这个变量 在客户端和服务器中。
http://dev.mysql.com/doc/refman/5.5/en/packet-too-large.html
不确定mysql_query的返回值是如何受此影响的,但值得研究。在my.cnf
中设置它以确定它是否能解决问题将是最佳起点。
答案 4 :(得分:0)
mysql_query不返回FALSE,更不用说TRUE了。它返回一个资源id,如果等于零,则将其视为FALSE。我的例子是说明布尔结果
$resource = mysql_query($query, $handle);
if (!$resource) throw some exception;
if (!$resource && strpos($query, 'SELECT')) {
throw new Exception('mysql_query() returned TRUE for SELECT');
}
答案 5 :(得分:-2)
对于返回结果集的SELECT, SHOW, DESCRIBE, EXPLAIN
和其他语句,mysql_query()在成功时返回资源,或在出错时返回FALSE。
对于其他类型的SQL语句,INSERT, UPDATE, DELETE, DROP
等,mysql_query()
在成功时返回TRUE
或在出错时返回FALSE
。
你说SELECTs正在返回布尔值true吗?不只是一个不为零的资源:)?
答案 6 :(得分:-2)
James试图说的是,如果查询已被采用并正确执行,函数mysql_query()只返回true。它与查询产生的结果无关。
如果要实际获取结果,请使用mysql_fetch_assoc()/ mysql_fetch_array()/ mysql_results()。