[英]Why does mysql_query() return TRUE with a SELECT statement?
根據mysql_query()
的手冊以及我所知道的關於我多次使用的 function 的所有信息,如果查詢是SELECT
,它可以返回資源或FALSE
。 然而它不時返回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
...
如果 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 使用您沒有獲得的資源,而不是連接。
盡管 mysql_query 的 C 版本在失去連接時返回零仍然很奇怪 - 如果可以,請嘗試以下補丁並重新安裝 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;
}
當你說它“返回 TRUE”時,你是如何測試它的? 你不會做這樣的事吧?
$result = mysql_query($sql);
if ($result == TRUE) { /* stuff */ }
如果是這樣,請記住,返回的所有非零、非空白、非空值都將評估為 TRUE。 您可以使用更嚴格的方法來驗證這一點:
if ($result === TRUE) { /* stuff */ }
這不僅評估等效性,還評估類型。 你在做類似 var_export($result); 的事情嗎? 檢查數據類型並驗證您是否真的得到了 boolean 的 TRUE 值?
讓我們換個角度來看,當mysql_query()
返回FALSE
時,這意味着無論出於何種原因,查詢嘗試都失敗了。 這意味着即使在它開始執行之前,您查詢出了問題,因此對數據庫沒有影響,或者查詢甚至無法到達可以看到數據庫的地步。
您沒有提到數據長度,但您應該檢查這是否被超過max_allowed_packet
調用。
當 MySQL 客戶端或 mysqld 服務器接收到大於 max_allowed_packet 字節的數據包時,它會發出 Packet too large 錯誤並關閉連接。 對於某些客戶端,如果通信數據包太大,您可能還會在查詢錯誤期間與 MySQL 服務器失去連接。
[...]
客戶端和服務器都有自己的 max_allowed_packet 變量,所以如果你想處理大數據包,你必須在客戶端和服務器中都增加這個變量。
http://dev.mysql.com/doc/refman/5.5/en/packet-too-large.html
不確定 mysql_query 返回值如何受此影響,但值得研究。 在my.cnf
中設置它以查看它是否可以解決問題將是最好的起點。
mysql_query 不返回 FALSE,更不用說 TRUE。 它返回一個資源 ID,如果等於零,則將其視為 FALSE。 我的例子是為了說明 boolean 結果
$resource = mysql_query($query, $handle);
if (!$resource) throw some exception;
if (!$resource && strpos($query, 'SELECT')) {
throw new Exception('mysql_query() returned TRUE for SELECT');
}
對於SELECT, SHOW, DESCRIBE, EXPLAIN
和其他返回結果集的語句,mysql_query() 成功時返回資源,錯誤時返回 FALSE。
對於其他類型的 SQL 語句、 INSERT, UPDATE, DELETE, DROP
等, mysql_query()
在成功時返回TRUE
,在錯誤時返回FALSE
。
你說選擇返回 boolean 是真的嗎? 不僅僅是一個不為零的資源:)?
詹姆斯想說的是,如果查詢已被正確執行並執行,function mysql_query() 只會返回 true。 它與查詢產生的結果無關。
如果要實際獲取結果,請使用 mysql_fetch_assoc()/mysql_fetch_array()/mysql_results()。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.