Make WordPress Core

Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#54998 closed defect (bug) (invalid)

Fatal error using admin_email_check_interval filter on PHP 8.0

Reported by: josklever's profile josklever Owned by:
Milestone: Priority: normal
Severity: minor Version: 5.9
Component: Login and Registration Keywords: php8
Focuses: Cc:

Description

I’m debugging an issue while logging in on a site running on PHP 8.0 (no issues on 7.4) and I’ve managed to isolate it to a single function call I’m using to disable admin e-mail verification messages during login.

Setup:

  • WordPress 5.9 (same with 5.8.x)
  • No plugins
  • Default theme Twenty Twenty (same with other themes)
  • mu-plugin with just 1 filter
  • PHP 8.0.15 (same with older 8.0.x versions)

Single line of code in wp-content/mu-plugins/my-mu-plugin.php:

add_filter( 'admin_email_check_interval', 0 );

Error when logging in:

Fatal error: Uncaught TypeError: call_user_func_array(): Argument #1 ($callback) must be a valid callback, no array or string given in
/.../wp-includes/class-wp-hook.php:307 Stack trace: #0
/.../wp-includes/plugin.php(189): WP_Hook->apply_filters() #1
/.../wp-login.php(1282): apply_filters() #2
{main} thrown in /.../wp-includes/class-wp-hook.php on line 307

A few other filters in the same plugin (removed for testing) don’t give any issues, so it’s this specific filter.

Workaround:
I’ve found another reference on a site for this filter using:

add_filter( 'admin_email_check_interval', '__return_false' );

and that seems to work, although that’s not what the documentation suggests on
https://developer.wordpress.org/reference/hooks/admin_email_check_interval/

Change History (4)

#1 @costdev
2 years ago

add_filter( 'admin_email_check_interval', 0 );

The above is indeed incorrect usage.

The documentation for admin_email_check_interval shows:

apply_filters( 'admin_email_check_interval', int $interval )

Meaning that int $interval is passed to your filter callback, not that add_filter() accepts an int.

The correct usage to return 0 is:

add_filter(
    'admin_email_check_interval',
    static function( $interval ) {
        // Some logic that results in 0.
        return 0;
    }
);

or, to just simply return 0:

add_filter( 'admin_email_check_interval', '__return_zero' );
Last edited 2 years ago by costdev (previous) (diff)

#2 @josklever
2 years ago

Thanks for your quick response.

Is this something that should be added/changed in the documentation? These filters (code snippets) are shared on various websites, fora etc, so it might generate more issues when people will upgrade to PHP 8.x. I've been searching for a few hours and couldn't find a good explanation.
Diclaimer: I'm not a developer, but I can use code.

#3 @johnbillion
2 years ago

  • Keywords php8 added
  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed

Using 0 as a callback was likely filling your PHP error logs with warnings prior to upgrading to PHP 8, and it was coincidental that it was working as expected. Using any other number would have resulted in the interval being set to 0 too, due to type coercion.

I don't think there's anything to fix here, the documentation for add_filter(), tutorials around the internet, and associated error messages are clear that the second parameter must be a callable. A better course of action would be to contact the author of the article where you got the original code from to suggest a correction if necessary.

#4 @josklever
2 years ago

I'm monitoring my error log, so I'm sure it didn't give any warning with PH 7.4. I'm using this mu-plugin on all the sites I manage (about 240) and have never seen a warning.
I'm not sure where I've found this snippet, because that was around the time that the filter was introduced (WP 5.3, November 2019).
I'll try to find and examine some more documentation about add_filter() and apply_filters().

Thanks again!

Note: See TracTickets for help on using tickets.