0

I found that init hook is being called twice and then I try to trace and find out wp-settings.php is also being called twice. I originally want to post a question to find out why. And after some code injection tests. I found out the reason and would like to share here and see if there is anyone have another insight or method or workaround which could avoid the "double calling".

And the following is the testing method for finding out, there could be other possibilities and methods. Anyone with similar mind in detailed performance tweak may take a look.

1 Answer 1

0

The following test is carried to find out why. Because the test will touch the core source code. Only do it if you feel comfortable to do so.

Testing environment

  • PHP 7.4.9
  • WordPress 5.5
  • No plugin and then tried 1 plugin to stop heartbeat. (make sure ajax is not interfering the experiment)
  • default theme
  • No 404 error (404 error will lead to other recalling of the core files sometimes which will lead the experiment hard to trace).
  • Clean Installation is assumed

Cautions: Prepare a set of temporary WP installation so that it is safe for tampering the source code.

Note: If just simply var_dump to output something on the screen. It may only display 1 message as if it run only once(But actually it is being called twice). Logging and output to a file shows more information.

Code injection tried, putting at the beginning of wp-settings.php (and tried also under init hook)

Since it is an experiment and reason digging.

// output content to a file which shows clearly how much time is run
$log_location = '/volumes/ram/test-internal.log';

// because debug_backtrace() give an object, put the string result to buffer and write to log file
ob_start();
print_r(debug_backtrace()); // 
$trace = ob_get_contents();
ob_end_clean();

// output
file_put_contents( $log_location, 'wp-settings' . "\n", FILE_APPEND);
file_put_contents( $log_location, $trace . "\n", FILE_APPEND);

File Require Trace Result

Array
(
    [0] => Array
        (
            [file] => /dev/wp-config.php
            [line] => 108
            [function] => require_once
        )

    [1] => Array
        (
            [file] => /dev/wp-load.php
            [line] => 37
            [args] => Array
                (
                    [0] => /dev/wp-config.php
                )

            [function] => require_once
        )

    [2] => Array
        (
            [file] => /dev/wp-blog-header.php
            [line] => 13
            [args] => Array
                (
                    [0] => /dev/wp-load.php
                )

            [function] => require_once
        )

    [3] => Array
        (
            [file] => /dev/index.php
            [line] => 17
            [args] => Array
                (
                    [0] => /dev/wp-blog-header.php
                )

            [function] => require
        )

)

According to the trace log, it shows that wp-settings.php is being called twice, the caller are

  • wp-load.php -> require wp-settings.php
  • wp-blog-header.php -> require wp-load.php so it duplicate the loading of everything inside wp-settings.php

respectively. Since the init hook is inside wp-settings.php, so even if there is no ajax calling, the init hook is at least being called twice. I think in the future if possible, if they are being optimised and reformed to load only once, is ideal and good for performance. If ajax checking is not available, the init action of the init hook will be called in every heartbeat.

implication and inspiration

So the implication is that, every time an init hook is run, it is being called at least twice. If there is no ajax test inside the action, it will be called in every heartbeat. a testing like this

add_action( 'init', 'run_something' );
function run_something() {
    // if not desired to be called by ajax heartbeat
    // just an illustrative example, further detailed testing is needed on developer's own need
    if( wp_doing_ajax() ) {
        return;
    }

    // any work
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.