ID: 44352
Updated by: [EMAIL PROTECTED]
Reported By: stein at visibone dot com
-Status: Assigned
+Status: Feedback
Bug Type: MySQLi related
Operating System: Windows 2000
PHP Version: 5.2.5
Assigned To: andrey
New Comment:
I can't reproduce the problem with mysqli/libmysql - neither 5.2 nor
5.3-dev. However, I saw it with mysqli/mysqlnd, which is due to a bug in
PHP's streams. I will fix the bug. Can you give more information?
I am using mysql 5.1.24-rc server and client library (+headers).
Libmysql reports a problem in the resolution of `bogushost.com`
I haven't still checked the problem with isset($mysqli->error)
[EMAIL PROTECTED]:~/dev/php5_3> ./php -r
'var_dump(mysqli_get_client_info());$c=new
mysqli("bogushost.com");var_dump(mysqli_connect_error());'
string(9) "5.1.24-rc"
Warning: mysqli::mysqli(): (HY000/2005): Unknown MySQL server host
'bogushost.com' (1) in Command line code on line 1
string(45) "Unknown MySQL server host 'bogushost.com' (1)"
--------------------------------------------------------------
[EMAIL PROTECTED]:~/dev/vanilla/php5_2> ./php -r
'var_dump(mysqli_get_client_info());$c=new
mysqli("bogushost.com");var_dump(mysqli_connect_error());'
string(9) "5.1.24-rc"
Warning: mysqli::mysqli(): (HY000/2005): Unknown MySQL server host
'bogushost.com' (1) in Command line code on line 1
string(45) "Unknown MySQL server host 'bogushost.com' (1)"
--------------------------------------------------------------
Previous Comments:
------------------------------------------------------------------------
[2008-03-08 22:26:54] [EMAIL PROTECTED]
Assigned to primary maintainer
------------------------------------------------------------------------
[2008-03-06 17:35:48] stein at visibone dot com
Description:
------------
If you don't like this cramming of 4 bugs in 1, please consider this
solely a report of bug #1 which is the most serious. Fix the first two
assert()'s in the reproduce code and call it a solved.
I think the mysqli connect-time error handling has a lot of bugs. I
hope you'll bear with this report of 4 separate bugs. They all
contribute to a very difficult time for PHP code to detect connection
failure (as opposed humans detecting it from warning messages in the
output). I hope someone will find this a useful analysis of what goes
wrong when connections go wrong.
Bug #1: a bad host (misspelled domain, server down) can't be detected
by mysqli_connect_error() or mysqli_connect_errno() -- they return empty
string and zero. I have a hunch that in bug #30051 he actually detected
this problem at first, but then he brought up his server on localhost
and it went away so he closed his submission. I think bug #31163
reported this problem and then died of neglect. Bug #31745 may have
suffered from it, but it seems to be more about exceptions versus error
messages.
Again, bug 1 is the most serious. It breaks Example#1 on
http://www.php.net/manual/en/function.mysqli-connect.php when there's no
MySQL server running on localhost. Bugs 2,3,4 make workarounds hard.
Bug #2: the object oriented constructor "new mysqli" never returns
FALSE. This was reported in bug #32818 but waived off as a non-bug
without explanation. The documentation for this constructor is smooshed
in with that of mysqli_connect(), where it states "Returns ... FALSE if
the connection failed". So I believe bug #32818 was not bogus, or the
documentation is.
Bug #3 $mysqli->error member never passes the isset() nor
property_exists() tests. Not when the connection fails, nor when it
works, nor after a good query, nor a bad. Maybe all mysqli properties
suffer from this. The reproduce code demonstrates the same lapse for
mysqli::error, mysqli::errno, and mysqli_result::num_rows. So this may
be a defect of mysqli or some faux pas of the PHP5 object model itself.
I could find no existing bug that described it.
Bug #4 mysqli object limbo. Connection failure is undetectable without
generating a warning. "new mysql" returns what is by every diagnostic a
mysqli object. (get_class(), instanceof, and is_a() all say it is.) But
if the connection failed, doing anything with the instance will give you
the ubiquitous and inscrutible "Couldn't fetch mysqli" warning.
Drastic workaround for object oriented (works around all four bugs):
$mysqli = @new mysqli(...);
if (NULL === @$mysqli->error) {
die('connect fail: ' . mysqli_connect_error());
}
This may break someday. It's undocumented what the error member should
do if the connection succeeds, but it acually does become the empty
string.
Gentle workaround for procedural, same as Example #2 in
mysqli_connect() manual page:
$link = @mysqli_connect(...);
if (FALSE === $link) {
die('connect fail: ' . mysqli_connect_error());
}
Although in either case the message will be blank for host errors.
I believe bug 1 is the serious one. Classic mysql_connect() doesn't
make this mistake. Bugs 2,3,4 are relatively minor quirks of the object
model. All four bugs together make connection errors difficult to
detect in the code.
Reproduce code:
---------------
http://www.visibone.com/php/mysqli_connect_bugs.php.txt
If you find this too verbose, please concentrate on the first two
assert()'s. Fix them and I'd call this issue closed.
Expected result:
----------------
Many of the assert()'s should fail, especially the ones commented "//
BUG"
Actual result:
--------------
Testing... 2 tables ...Done.
(or a different number of tables)
I.e. no warnings, all assert()'s pass.
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=44352&edit=1