簡體   English   中英

為什么 mysql_query() 使用 SELECT 語句返回 TRUE?

[英]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');
}

PHP 布爾值

對於SELECT, SHOW, DESCRIBE, EXPLAIN和其他返回結果集的語句,mysql_query() 成功時返回資源,錯誤時返回 FALSE。

對於其他類型的 SQL 語句、 INSERT, UPDATE, DELETE, DROP等, mysql_query()在成功時返回TRUE ,在錯誤時返回FALSE

(來自http://php.net/manual/en/function.mysql-query.php

你說選擇返回 boolean 是真的嗎? 不僅僅是一個不為零的資源:)?

詹姆斯想說的是,如果查詢已被正確執行並執行,function mysql_query() 只會返回 true。 它與查詢產生的結果無關。

如果要實際獲取結果,請使用 mysql_fetch_assoc()/mysql_fetch_array()/mysql_results()。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM