ID:               44352
 User updated by:  stein at visibone dot com
 Reported By:      stein at visibone dot com
 Status:           Open
 Bug Type:         MySQLi related
 Operating System: Windows 2000
 PHP Version:      5.2.5
 Assigned To:      andrey
 New Comment:

...and with warnings (no @ sign) I get:

string(46) "mysqlnd 5.0.1-beta - 070402 - $Revision: 321 $"
PHP Warning:  mysqli::mysqli(): php_network_getaddresses: getaddrinfo
failed: No such host is known.  in Command line code on line 1

Warning: mysqli::mysqli(): php_network_getaddresses: getaddrinfo
failed: No such host is known.  in Command line code on line 1
PHP Warning:  mysqli::mysqli(): (00000/0):  in Command line code on
line 1

Warning: mysqli::mysqli(): (00000/0):  in Command line code on line 1
string(0) ""


Previous Comments:
------------------------------------------------------------------------

[2008-03-11 09:40:33] stein at visibone dot com

Good test case.  For windows command line I swapped the quote marks. 
With warnings suppressed I get:

C:\>php -r "var_dump(mysqli_get_client_info());[EMAIL PROTECTED]
mysqli('bogushost.com');var_dump(mysqli_connect_error());"

string(46) "mysqlnd 5.0.1-beta - 070402 - $Revision: 321 $"
string(0) ""

------------------------------------------------------------------------

[2008-03-10 19:15:14] [EMAIL PROTECTED]

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)"

--------------------------------------------------------------


------------------------------------------------------------------------

[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

Reply via email to