Critical Bug in Enterprise_Dbcache_WpdbInjection_Cluster.php causing mysqli_num_
-
Dear W3 Total Cache Development Team,
I’m writing to report a critical issue in your W3 Total Cache plugin that is causing fatal errors on WordPress sites when used alongside the Daftplug Progressify plugin. The issue occurs in the database caching component. Error Details
Fatal error: Uncaught TypeError: mysqli_num_fields(): Argument #1 ($result) must be of type mysqli_result, bool given in /wp-content/plugins/w3-total-cache/Enterprise_Dbcache_WpdbInjection_Cluster.php:727Problem Description
The error occurs because the
mysqli_num_fields()function is being called with a boolean value instead of a mysqli_result object. This happens when:- The Daftplug Progressify plugin executes
dbDelta()to create tables during WordPress initialization - The
dbDelta()function uses a query withCREATE TABLE IF NOT EXISTSsyntax - During the table creation process, it attempts to run a
DESCRIBE IF;query (where “IF” is a MySQL reserved word) - Your W3 Total Cache database caching layer intercepts this query but doesn’t properly handle the boolean result
Root Cause
The issue is in the
query()method inEnterprise_Dbcache_WpdbInjection_Cluster.php, where there are no type checks before callingmysqli_num_fields(). When certain query types return boolean values (especially those fromdbDelta()), the function attempts to pass these boolean values tomysqli_num_fields(), which expects a mysqli_result object. Suggested FixI’ve identified a solution that works by adding type checking before using the result. Here’s the patched version of the affected part of the
query()method:php
else { $i = 0; $this->wpdb_mixin->col_info = array(); $col_info = array(); // Add type checking before calling mysqli_num_fields() if (is_object($this->wpdb_mixin->result) && !is_bool($this->wpdb_mixin->result)) { while ( $i < @mysqli_num_fields( $this->wpdb_mixin->result ) ) { $col_info[ $i ] = @mysqli_fetch_field( $this->wpdb_mixin->result ); ++$i; } } $this->wpdb_mixin->col_info = $col_info; $num_rows = 0; $this->wpdb_mixin->last_result = array(); // Add type checking before fetching rows if (is_object($this->wpdb_mixin->result) && !is_bool($this->wpdb_mixin->result)) { do { $row = @mysqli_fetch_object( $this->wpdb_mixin->result ); if ( $row ) { $this->wpdb_mixin->last_result[ $num_rows ] = $row; ++$num_rows; } } while ( $row ); }The changes ensure that
mysqli_num_fields()is only called when$this->wpdb_mixin->resultis an object, not a boolean value. Additional Context- WordPress Version: Latest
- W3 Total Cache Version: Enterprise edition
- Conflicting plugin: Daftplug Progressify
- The issue occurs on both PHP 7.x and PHP 8.x environments
Impact
This bug prevents users from accessing their WordPress admin area and effectively breaks their sites when both plugins are active.
I hope you can include this fix in your next update. Please let me know if you need any additional information.
Thank you for your attention to this matter.
- The Daftplug Progressify plugin executes
The topic ‘Critical Bug in Enterprise_Dbcache_WpdbInjection_Cluster.php causing mysqli_num_’ is closed to new replies.