Intereting Posts

Почему mysql_query () возвращает TRUE с помощью инструкции SELECT?

Согласно руководству 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

Если 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 } } 

Я считаю это ошибкой. Тем более, что нет реального способа проверить это – mysql_num_fields в коде PHP использует ресурс, который вы не получаете, а не соединение.

Хотя по-прежнему странно, что версия 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 */ } 

Если это так, имейте в виду, что все ненулевые, непустые, ненулевые значения, которые будут возвращены, будут оцениваться в ИСТИНА. Вы можете проверить это, используя более строгие:

 if ($result === TRUE) { /* stuff */ } 

Это оценивает не только эквивалентность, но и тип. Вы делаете что-то вроде var_export ($ result); проверить тип данных и убедиться, что вы действительно возвращаете логическое значение TRUE?

Давайте посмотрим на это другим способом. Когда mysql_query() возвращает FALSE это означает, что по какой-либо причине попытка запроса не сработала. Это означает, что даже до того, как это произошло, вы спросите, что-то пошло не так, как таковое не повлияло на базу данных или что запрос не смог даже добраться до точки, где он мог видеть базу данных.

Вы не max_allowed_packet длину данных, но вы должны проверить, max_allowed_packet ли это превышением 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 чтобы определить, будет ли он исправлять проблему, будет лучшим местом для начала.

mysql_query не возвращает FALSE, не говоря уже о TRUE. Он возвращает идентификатор ресурса, который приравнивается к нулю, считается принятым как ЛОЖЬ. Мой пример – проиллюстрировать логические результаты

 $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-булевы

То, что Джеймс пытался сказать, заключается в том, что функция mysql_query () просто возвращает true, если запрос был выполнен и выполнен правильно. Это не имеет ничего общего с результатами, которые дает запрос.

Если вы хотите получить результаты, используйте mysql_fetch_assoc () / mysql_fetch_array () / mysql_results ().

Для SELECT, SHOW, DESCRIBE, EXPLAIN и других операторов, возвращающих набор результатов, mysql_query () возвращает ресурс с успехом или FALSE при ошибке.

Для других типов операторов SQL INSERT, UPDATE, DELETE, DROP и т. Д. mysql_query() возвращает TRUE при успешном mysql_query() или FALSE при ошибке.

(из http://php.net/manual/en/function.mysql-query.php )

Вы говорите, что SELECTs возвращают логическое значение true? Не только ресурс, который не равен нулю :)?