I’m getting the escaping notice too. Spent a little time debugging and the notice is generated from the _real_escape()
method in wpdb
. This happens if mysql_connect() can’t open a connection to the db.
I’m pretty sure this is just because hyperdb doesn’t connect until it needs to so if a string is being escaped before the first write you get the doing_it_wrong notice because a connection hasn’t been made yet. When this happens _real_escape() uses addslashes instead of mysql_real_escape.
I’m going to look into this little more when I have time. Maybe someone else has some insight.
This happens because prepare is called before any query is executed. It calls _real_escape which fails because the connection is not opened by hyperdb until a query is sent to the server.
I am seeing this error on the back-end, and it’s generated from WP core.
First, a stack trace:
PHP Notice: hyperdb was called <strong>incorrectly</strong>. hyperdb must set a database connection for use with escaping. Please see <a href="http://codex.wordpress.org/Debugging_in_WordPress">Debugging in WordPress</a> for more information. (This message was added in version 1024.) in core/wp-includes/functions.php on line 3049
PHP Stack trace:
PHP 1. {main}() core/wp-admin/post.php:0
PHP 2. require_once() core/wp-admin/post.php:12
PHP 3. get_option() core/wp-admin/admin.php:34
PHP 4. wpdb->prepare() core/wp-includes/option.php:61
PHP 5. array_walk() core/wp-includes/wp-db.php:1005
PHP 6. wpdb->escape_by_ref() core/wp-includes/wp-db.php:1005
PHP 7. wpdb->_real_escape() core/wp-includes/wp-db.php:952
PHP 8. _doing_it_wrong() core/wp-includes/wp-db.php:883
PHP 9. trigger_error() core/wp-includes/functions.php:3049
The error is generated when get_option() is hit, because prepare()
is called before a DB connection has been made, and prepare()
proxies to $wpdb->_real_escape()
, which requires a DB connection to call mysql_real_escape_string()
.
I’m not sure what the best solution here should be. HyperDB could define its own method prepare()
, which establishes a database connection and then invokes parent prepare()
.
A few options.
Add this to HyperDB. It will establish a database connection before triggering the business of a prepare()
call
/**
* Prepare requires a database connection, so let's establish one and then
* call $wpdb->prepare().
*
* @param type $query
* @param type $args
*/
function prepare( $query, $args ) {
if ( ! $this->dbh ) {
$dbh = $this->db_connect( 'SELECT 1' );
if ( ! $this->dbh )
$this->dbh = $dbh;
}
parent::prepare( $query, $args );
}
Add this to HyperDB, a modified version of the same method in $wpdb
, excluding the _doing_it_wrong()
call. Props @wonderboymusic.
/**
* Real escape, using mysql_real_escape_string()
*
* @see mysql_real_escape_string()
* @since 2.8.0
* @access private
*
* @param string $string to escape
* @return string escaped
*/
function _real_escape( $string ) {
if ( $this->dbh )
return mysql_real_escape_string( $string, $this->dbh );
return addslashes( $string );
}
I’m more into the latter.
Aaaaand this is fixed in the latest version of HyperDB.
It’d be nice if they put a version comment block in the header of the dropin…
As well as a version on the plugin page… https://wordpress.org/plugins/hyperdb/