• williamrast

    (@williamrast)


    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:727

    Problem 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:

    1. The Daftplug Progressify plugin executes dbDelta() to create tables during WordPress initialization
    2. The dbDelta() function uses a query with CREATE TABLE IF NOT EXISTS syntax
    3. During the table creation process, it attempts to run a DESCRIBE IF; query (where “IF” is a MySQL reserved word)
    4. 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 in Enterprise_Dbcache_WpdbInjection_Cluster.php, where there are no type checks before calling mysqli_num_fields(). When certain query types return boolean values (especially those from dbDelta()), the function attempts to pass these boolean values to mysqli_num_fields(), which expects a mysqli_result object. Suggested Fix

    I’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->result is 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.

Viewing 15 replies - 1 through 15 (of 16 total)
  • Plugin Contributor Marko Vasiljevic

    (@vmarko)

    Hello @williamrast

    Thank you for reaching out and taking the time to repport this!
    I’ll share this with the team, and I’ll get back to you if the ticket is submitted for this and with more details.

    Thank you again!

    Plugin Contributor Marko Vasiljevic

    (@vmarko)

    Hello @williamrast

    Thank you for your patience
    Can you please change the line Enterprise_Dbcache_WpdbInjection_Cluster.php Line 444 to:

    if ( is_a( $this->wpdb_mixin->result, 'mysqli_result' ) ) {

    Please let me know if this helps so we can include this in the release

    Thanks!

    Thread Starter williamrast

    (@williamrast)

    Hello @vmarko

    Thank you for your quick response and suggested fix. Unfortunately, after implementing the change you recommended (modifying line 444 with if ( is_a( $this->wpdb_mixin->result, 'mysqli_result' ) ) {), the error still persists. Observed Error

    The same error continues to appear:

    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:727

    Issue Analysis

    After further analysis, I’ve identified that:

    1. The error occurs at line 727, not line 444
    2. The stack trace shows mysqli_num_fields(true) is being called with a boolean value
    3. Your check at line 444 doesn’t affect the execution path that reaches line 727

    Proposed Solution

    I’ve implemented a different fix that successfully resolves the issue. It involves adding type checking directly before both calls that can cause errors:

    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 );
        }

    These changes ensure that both critical sections that interact with the mysqli_result object are properly protected with type checking. The fix works by:

    1. Only attempting to call mysqli_num_fields() when the result is an actual object (not a boolean)
    2. Similarly protecting the row fetching loop
    3. Maintaining all the variables and arrays to preserve the method’s logic

    I’ve verified this solution successfully resolves the conflict with the Daftplug Progressify plugin while maintaining W3 Total Cache functionality.

    I’d be happy to provide any additional information or testing to help resolve this issue in the official release.

    Plugin Contributor Marko Vasiljevic

    (@vmarko)

    Hello @williamrast

    Thank you for your feedback.
    Sorry for the typo, I meant line 727.

    The W3TC 2.8.9 is ready for pre-release testing. Is there any chance you can test this and let me know if this resolves the problem for you?

    Thanks!

    Thread Starter williamrast

    (@williamrast)

    Hello @vmarko

    Fatal error: Uncaught TypeError: mysqli_fetch_object(): Argument #1 ($result) must be of type mysqli_result, bool given in /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/Enterprise_Dbcache_WpdbInjection_Cluster.php:739 Stack trace: #0 /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/Enterprise_Dbcache_WpdbInjection_Cluster.php(739): mysqli_fetch_object(true) #1 /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/DbCache_WpdbNew.php(217): W3TC\Enterprise_Dbcache_WpdbInjection_Cluster->query(‘CREATE TABLE IF…’) #2 /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/DbCache_WpdbNew.php(664): W3TC\DbCache_WpdbNew->query(‘CREATE TABLE IF…’) #3 /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/DbCache_WpdbInjection_QueryCaching.php(213): W3TC\_CallUnderlying->query(‘CREATE TABLE IF…’) #4 /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/DbCache_WpdbNew.php(217): W3TC\DbCache_WpdbInjection_QueryCaching->query(‘CREATE TABLE IF…’) #5 /var/www/www-root/data/www/ap71.tw1.ru/wp-admin/includes/upgrade.php(3280): W3TC\DbCache_WpdbNew->query(‘CREATE TABLE IF…’) #6 /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/_daftplug-progressify/includes/modules/dashboard.php(71): dbDelta(Array) #7 /var/www/www-root/data/www/ap71.tw1.ru/wp-includes/class-wp-hook.php(324): DaftPlug\Progressify\Module\Dashboard->createPwaUsersTable(”) #8 /var/www/www-root/data/www/ap71.tw1.ru/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #9 /var/www/www-root/data/www/ap71.tw1.ru/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #10 /var/www/www-root/data/www/ap71.tw1.ru/wp-settings.php(727): do_action(‘init’) #11 /var/www/www-root/data/www/ap71.tw1.ru/wp-config.php(140): require_once(‘/var/www/www-ro…’) #12 /var/www/www-root/data/www/ap71.tw1.ru/wp-load.php(50): require_once(‘/var/www/www-ro…’) #13 /var/www/www-root/data/www/ap71.tw1.ru/wp-admin/admin.php(35): require_once(‘/var/www/www-ro…’) #14 /var/www/www-root/data/www/ap71.tw1.ru/wp-admin/plugin-install.php(16): require_once(‘/var/www/www-ro…’) #15 {main} thrown in /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/Enterprise_Dbcache_WpdbInjection_Cluster.php on line 739

    Thread Starter williamrast

    (@williamrast)

    @vmarko Here is the plugin for your testing. A license is not required.

    https://drive.google.com/file/d/1y0nUz9X00z2R7YzowGR39a3exrzFTdeK/view?usp=sharing

    Plugin Contributor Marko Vasiljevic

    (@vmarko)

    Hello @williamrast

    Thank you for the information

    We’ll check this and get back to you as soon as a dev team has a solution
    Thanks!

    Thread Starter williamrast

    (@williamrast)

    Hello @vmarko
    Why you don’t use my solution?

    Plugin Contributor Marko Vasiljevic

    (@vmarko)

    Hello @williamrast

    Thank you for your feedback.
    We’ll implement this and make tests.
    Thank you!

    Thread Starter williamrast

    (@williamrast)

    Hello @vmarko I still get the error

    Thread Starter williamrast

    (@williamrast)

    Fatal error: Uncaught TypeError: mysqli_fetch_object(): Argument #1 ($result) must be of type mysqli_result, bool given in /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/Enterprise_Dbcache_WpdbInjection_Cluster.php:739 Stack trace: #0 /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/Enterprise_Dbcache_WpdbInjection_Cluster.php(739): mysqli_fetch_object(true) #1 /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/DbCache_WpdbNew.php(217): W3TC\Enterprise_Dbcache_WpdbInjection_Cluster->query(‘CREATE TABLE IF…’) #2 /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/DbCache_WpdbNew.php(664): W3TC\DbCache_WpdbNew->query(‘CREATE TABLE IF…’) #3 /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/DbCache_WpdbInjection_QueryCaching.php(213): W3TC\_CallUnderlying->query(‘CREATE TABLE IF…’) #4 /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/DbCache_WpdbNew.php(217): W3TC\DbCache_WpdbInjection_QueryCaching->query(‘CREATE TABLE IF…’) #5 /var/www/www-root/data/www/ap71.tw1.ru/wp-admin/includes/upgrade.php(3280): W3TC\DbCache_WpdbNew->query(‘CREATE TABLE IF…’) #6 /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/daftplug-progressify/includes/modules/dashboard.php(71): dbDelta(Array) #7 /var/www/www-root/data/www/ap71.tw1.ru/wp-includes/class-wp-hook.php(324): DaftPlug\Progressify\Module\Dashboard->createPwaUsersTable(”) #8 /var/www/www-root/data/www/ap71.tw1.ru/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #9 /var/www/www-root/data/www/ap71.tw1.ru/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #10 /var/www/www-root/data/www/ap71.tw1.ru/wp-settings.php(727): do_action(‘init’) #11 /var/www/www-root/data/www/ap71.tw1.ru/wp-config.php(140): require_once(‘/var/www/www-ro…’) #12 /var/www/www-root/data/www/ap71.tw1.ru/wp-load.php(50): require_once(‘/var/www/www-ro…’) #13 /var/www/www-root/data/www/ap71.tw1.ru/wp-admin/admin.php(35): require_once(‘/var/www/www-ro…’) #14 /var/www/www-root/data/www/ap71.tw1.ru/wp-admin/plugin-install.php(16): require_once(‘/var/www/www-ro…’) #15 {main} thrown in /var/www/www-root/data/www/ap71.tw1.ru/wp-content/plugins/w3-total-cache/Enterprise_Dbcache_WpdbInjection_Cluster.php on line 739

    Plugin Contributor Marko Vasiljevic

    (@vmarko)

    Hello @williamrast

    Can you please open a ticket for this in our Github repo so the devs can take a look at this and check your solution?

    Thanks!

    error when using W3 Total Cache 2.8.10 with WooCommerce Advanced Bulk Edit 5.5.3.4 :

    the products are not shown on Advanced Bulk Edit..

    Fatal error: Uncaught TypeError: mysqli_fetch_object(): Argument #1 ($result) must be of type mysqli_result, bool given in /home/menasimcom/public_html/wp-content/plugins/w3-total-cache/Enterprise_Dbcache_WpdbInjection_Cluster.php:739 Stack trace: #0 /home/menasimcom/public_html/wp-content/plugins/w3-total-cache/Enterprise_Dbcache_WpdbInjection_Cluster.php(739): mysqli_fetch_object() #1 /home/menasimcom/public_html/wp-content/plugins/w3-total-cache/DbCache_WpdbNew.php(217): W3TC\Enterprise_Dbcache_WpdbInjection_Cluster->query() #2 /home/menasimcom/public_html/wp-content/plugins/w3-total-cache/DbCache_WpdbNew.php(664): W3TC\DbCache_WpdbNew->query() #3 /home/menasimcom/public_html/wp-content/plugins/w3-total-cache/DbCache_WpdbInjection_QueryCaching.php(213): W3TC\_CallUnderlying->query() #4 /home/menasimcom/public_html/wp-content/plugins/w3-total-cache/DbCache_WpdbNew.php(217): W3TC\DbCache_WpdbInjection_QueryCaching->query() #5 /home/menasimcom/public_html/wp-content/plugins/woocommerce-advanced-bulk-edit/ajax_handler.php(788): W3TC\DbCache_WpdbNew->query() #6 /home/menasimcom/public_html/wp-content/plugins/woocommerce-advanced-bulk-edit/ajax_handler.php(8163): W3ExABulkEditAjaxHandler::loadProducts() #7 /home/menasimcom/public_html/wp-content/plugins/woocommerce-advanced-bulk-edit/woocommerce-advanced-bulk-edit.php(364): W3ExABulkEditAjaxHandler::ajax() #8 /home/menasimcom/public_html/wp-includes/class-wp-hook.php(324): W3ExAdvancedBulkEditMain::ajax_request() #9 /home/menasimcom/public_html/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters() #10 /home/menasimcom/public_html/wp-includes/plugin.php(517): WP_Hook->do_action() #11 /home/menasimcom/public_html/wp-admin/admin-ajax.php(192): do_action() #12 {main} thrown in /home/menasimcom/public_html/wp-content/plugins/w3-total-cache/Enterprise_Dbcache_WpdbInjection_Cluster.php on line 739

    There has been a critical error on this website.

    Learn more about troubleshooting WordPress.

    Thread Starter williamrast

    (@williamrast)

    Hello @vmarko

    I posted it https://github.com/BoldGrid/w3-total-cache/issues/1120, but no one is responding. It’s like you’ve been mocking me for two months. What’s so difficult about posting the suggested code???

    Thread Starter williamrast

    (@williamrast)

    Hello @vmarko

    I posted it https://github.com/BoldGrid/w3-total-cache/issues/1120, but no one is responding. It’s like you’ve been mocking me for four months. What’s so difficult about posting the suggested code???

Viewing 15 replies - 1 through 15 (of 16 total)

The topic ‘Critical Bug in Enterprise_Dbcache_WpdbInjection_Cluster.php causing mysqli_num_’ is closed to new replies.