[wp-trac] [WordPress Trac] #54877: Occasional PHP exception being thrown on WPDB/MySQLi connections

WordPress Trac noreply at wordpress.org
Fri Jan 21 19:06:32 UTC 2022

#54877: Occasional PHP exception being thrown on WPDB/MySQLi connections
 Reporter:  johnjamesjacoby  |      Owner:  (none)
     Type:  enhancement      |     Status:  new
 Priority:  normal           |  Milestone:  6.0
Component:  Database         |    Version:  1.5
 Severity:  normal           |   Keywords:  2nd-opinion
  Focuses:                   |
 ** PHP Debug Notice **
 mysqli::real_connect() expects parameter 5 to be integer, string given -
 wpdb::_do_query /wp-includes/wp-db.php:2056

 The above notice appears in logs once for approximately every 250k
 requests. I have a hunch it's happening on reconnection attempts (using
 `$this->dbh`) but don't have any hard evidence to back up that claim.

 My `DB_HOST` is `localhost`, and I've also seen this happen with RDS


 I've spent a few hours researching this, and am including that research

 **WordPress DB_HOST Documentation**
 * https://wordpress.org/support/article/editing-wp-config-php/#set-

 The above docs confirm that `localhost:3306` is the recommended way of
 adding a port number.

 **CodeIgniter example & fix**
 * https://github.com/bcit-ci/CodeIgniter/issues/5627
 * https://github.com/bcit-

 The above links confirm that CodeIgniter was defaulting to a string
 (causing the same issue) instead of null or int, and patched it

 **Facebook, HHVM, HACK**
 * https://github.com/facebook/hhvm/issues/2482

 The above issue confirms that Facebook saw the same issue, and decided to
 patch it inside of HHVM.

 **Tangential WordPress tickets**
 * #41722 - Adding IPv6 support
 * #42496 - Improving MySQL 8.0 support
 * #21663 - Adding mysqli support

 The above tickets show an abbreviated timeline of surrounding changes to
 wpdb. No regressions. No bug introductions. Simply some related research.

 **PHP MySQL unit tests**
 * https://github.com/php/pecl-database-

 The above link shows how PHP itself tests MySQL (not MySQLi) database

 **PHP MySQLi Docs**
 * https://www.php.net/manual/en/class.mysqli.php

 The above link is my favorite. Specifically:

 class mysqli {
     public __construct(
         string $hostname = ini_get("mysqli.default_host"),
         string $username = ini_get("mysqli.default_user"),
         string $password = ini_get("mysqli.default_pw"),
         string $database = "",
         int $port = ini_get("mysqli.default_port"),
         string $socket = ini_get("mysqli.default_socket")
     public real_connect(
         string $host = ?,
         string $username = ?,
         string $passwd = ?,
         string $dbname = ?,
         int $port = ?,
         string $socket = ?,
         int $flags = ?
     ): bool

 `ini_get()` always returns a string, and PHP's mysqli class constructs &
 defaults its `$port` using it. In the PHP source, it does not appear to be
 type cast into an integer.



 I believe this small and random-feeling annoyance can be fixed quite
 easily in WordPress in much the same way it's been fixed in HHVM &

 I have a hunch that: web hosts silence or ignore these notices; they've
 been happening for a very long time; the problem is small enough where it
 wasn't worth anyone else digging too deep into.



 * `wpdb::parse_db_host()` parses `$this->dbhost` looking for IPv4/IPv6,
 port number, sockets, etc...
 * `$this->dbhost` is gotten from `DB_HOST`
 * Casting `$post` to `(int)` when non-null will ensure
 `mysqli_real_connect()` will only ever see `null` or `int` type values

 Something like:
 $port = $port ? absint( $port ) : null;

Ticket URL: <https://core.trac.wordpress.org/ticket/54877>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform

More information about the wp-trac mailing list