php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71803 MySQLi doesn't properly update connection error with persistent connections
Submitted: 2016-03-11 18:23 UTC Modified: 2021-07-11 04:22 UTC
Votes:7
Avg. Score:4.7 ± 0.5
Reproduced:7 of 7 (100.0%)
Same Version:5 (71.4%)
Same OS:5 (71.4%)
From: jeff dot minard at creditkarma dot com Assigned: cmb (profile)
Status: No Feedback Package: MySQLi related
PHP Version: 5.6.19 OS: CentOS
Private report: No CVE-ID: None
 [2016-03-11 18:23 UTC] jeff dot minard at creditkarma dot com
Description:
------------
Essentially, it would appear that when creating a mysql connection, without persistence, each time you call the mysqli_connect() method it will clear the "last error" state value so calls to mysqli_connect_error() work correctly.

However, when you user presistent connections this doesn't work correctly. I suspect that the mysqli_connect() method is, when doing persistence, shortcutting the method and not clearing the state for what mysqli_connect_error() reads from. IE:

function mysqli_connect(...params) {
  if (host is persistent) {
    setup persistentHost
    return true
  }
  clearErrorState()
  doNormalConnectStuff()
}

As terrible psuedo code, I suspect that something like that is happening which causes the state to not reset until the next real connection happens (instead of pulling an existing connection from the pool).

Test script:
---------------
<?php

$mysql1 = '172.17.0.67';
$mysql2 = '172.17.0.69';

$conn = @mysqli_connect($mysql1, 'root', 'root', 'mysql', '3306');
echo "Err?: " . ( $conn ? 'connected' : 'conn fail' ) . ' -- ' . mysqli_connect_errno() . ': ' . mysqli_connect_error() . "\n";

$conn = @mysqli_connect($mysql2, 'root', 'root', 'mysql', '3307'); // note: WRONG PORT
echo "Err?: " . ( $conn ? 'connected' : 'conn fail' ) . ' -- ' . mysqli_connect_errno() . ': ' . mysqli_connect_error() . "\n";

$conn = @mysqli_connect($mysql1, 'root', 'root', 'mysql', '3306');
echo "Err?: " . ( $conn ? 'connected' : 'conn fail' ) . ' -- ' . mysqli_connect_errno() . ': ' . mysqli_connect_error() . "\n";

$conn = @mysqli_connect($mysql2, 'root', 'root', 'mysql', '3306');
echo "Err?: " . ( $conn ? 'connected' : 'conn fail' ) . ' -- ' . mysqli_connect_errno() . ': ' . mysqli_connect_error() . "\n";

$mysql1 = 'p:' . $mysql1;
$mysql2 = 'p:' . $mysql2;

$conn = @mysqli_connect($mysql1, 'root', 'root', 'mysql', '3306');
echo "Err?: " . ( $conn ? 'connected' : 'conn fail' ) . ' -- ' . mysqli_connect_errno() . ': ' . mysqli_connect_error() . "\n";

$conn = @mysqli_connect($mysql2, 'root', 'root', 'mysql', '3307'); // note: WRONG PORT
echo "Err?: " . ( $conn ? 'connected' : 'conn fail' ) . ' -- ' . mysqli_connect_errno() . ': ' . mysqli_connect_error() . "\n";

$conn = @mysqli_connect($mysql1, 'root', 'root', 'mysql', '3306');
echo "Err?: " . ( $conn ? 'connected' : 'conn fail' ) . ' -- ' . mysqli_connect_errno() . ': ' . mysqli_connect_error() . "\n";

$conn = @mysqli_connect($mysql2, 'root', 'root', 'mysql', '3306');
echo "Err?: " . ( $conn ? 'connected' : 'conn fail' ) . ' -- ' . mysqli_connect_errno() . ': ' . mysqli_connect_error() . "\n";

Expected result:
----------------
Err?: connected -- 0:
Err?: conn fail -- 2003: Can't connect to MySQL server on '172.17.0.69' (111)
Err?: connected -- 0:
Err?: connected -- 0:
Err?: connected -- 0:
Err?: conn fail -- 2003: Can't connect to MySQL server on '172.17.0.69' (111)
Err?: connected -- 0:
Err?: connected -- 0:

Actual result:
--------------
Err?: connected -- 0:
Err?: conn fail -- 2003: Can't connect to MySQL server on '172.17.0.69' (111)
Err?: connected -- 0:
Err?: connected -- 0:
Err?: connected -- 0:
Err?: conn fail -- 2003: Can't connect to MySQL server on '172.17.0.69' (111)
Err?: connected -- 2003: Can't connect to MySQL server on '172.17.0.69' (111)
Err?: connected -- 0:

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-03-11 18:42 UTC] jeff dot minard at creditkarma dot com
Looks like the mysqli c code from here:

https://github.com/php/php-src/blob/71c19800258ee3a9548af9a5e64ab0a62d1b1d8e/ext/mysqli/mysqli_nonapi.c#L186

Will jump over this

https://github.com/php/php-src/blob/71c19800258ee3a9548af9a5e64ab0a62d1b1d8e/ext/mysqli/mysqli_nonapi.c#L259

Which means the errors don't get reset even though the "connect" call was successful.
 [2017-03-21 00:24 UTC] domainadmin at digitalaxcess dot com
This happens also when script wants to create two separate mysqli connections.

Example:

$db_host1 = 'localhostinvalid';
$db_host2 = 'localhost';
$db_user = 'username';
$db_pass = 'password';
$db_name = 'dbname';

$db1 = @new mysqli($db_host1, $db_user, $db_pass, $db_name);
if ($db1->connect_errno) { echo $db1->connect_error.'<br/>'; } else { echo 'Ok<br/>';}

$db2 = @new mysqli($db_host2, $db_user, $db_pass, $db_name);
if ($db1->connect_errno) { echo $db1->connect_error.'<br/>'; } else { echo 'Ok<br/>';}

Result:
php_network_getaddresses: getaddrinfo failed: Name or service not known
Access denied for user 'username'@'localhost' (using password: YES)

$db1 will fail as it tries to connect to an invalid host, and the error message will indicate so. Note that second "if" operates again on $db1, and the error message of $db1->connect_error will be overwritten by whatever happened to $db2 (second connection), or if $db2 connection was successful, $db1 will indicate the same even though $db1 wasn't successful and "Ok" will be printed. Tested on 5.5 and 7.0.
 [2017-04-02 14:50 UTC] tpunt@php.net
-Package: mysql +Package: MySQLi related
 [2017-10-23 15:46 UTC] bjori@php.net
-Assigned To: +Assigned To: bjori
 [2019-09-09 02:44 UTC] bjori@php.net
-Status: Assigned +Status: Open -Assigned To: bjori +Assigned To:
 [2021-07-02 16:28 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2021-07-02 16:28 UTC] cmb@php.net
I cannot reproduce this with PHP-7.4.  Is this still an issue for
you with any of the actively supported PHP versions[1]?

[1] <https://www.php.net/supported-versions.php>
 [2021-07-11 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC