WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 4 years ago

#16749 closed defect (bug) (worksforme)

Hooks alter/break array-formatted callbacks

Reported by: Veraxus Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.1
Component: General Keywords:
Focuses: Cc:

Description

When hooking to static methods of a class (plugin, theme, etc), there are two possible formats:

array('class','method') or 'class::method'

The prior works on PHP 4+, where the latter requires PHP 5.2.3+

The problem is that any time I try to use an array-formatted callback with a WordPress hook (for maximum compatibility), PHP throws an invalid callback error for wp-includes/plugin.php.

It turns out that the array ultimately being passed to call_user_func_array() always has an integer 1 appended to the array... thus making the callback invalid as call_user_func_array() is now being sent this:

array('class','function',1)

String-formatted callbacks work perfectly, but array-formatted callbacks are altered and therefore broken. This can be fixed by adding the following check to four different functions in plugin.php (apply_filters(), apply_filters_ref_array(), do_action(), and do_action_ref_array()), but I'm not sure this is the "best" solution.

Here's the "corrective" check:

if(is_array($the_['function']) && isset($the_['function'][2])){
   unset($the_['function'][2]);
}

Change History (5)

comment:1 @scribu4 years ago

  • Keywords reporter-feedback added

I use array callbacks all the time without problems.

Are you sure there's not something else going on?

comment:2 follow-up: @scribu4 years ago

Maybe you're adding the priority in the array by mistake:

add_action( 'foo', array( 'class', 'method, 1 ) );

comment:3 in reply to: ↑ 2 @westi4 years ago

  • Keywords reporter-feedback removed
  • Milestone Awaiting Review deleted
  • Resolution set to worksforme
  • Severity changed from major to normal
  • Status changed from new to closed

Replying to scribu:

Maybe you're adding the priority in the array by mistake:

add_action( 'foo', array( 'class', 'method, 1 ) );

That exactly how he shows it in the ticket description which is incorrect.

comment:4 @Veraxus4 years ago

  • Resolution worksforme deleted
  • Status changed from closed to reopened

No, I've confirmed the callback is being entered correctly.

For instance, here's one of the problem hooks:

add_action('admin_init', array('CTXPS_App','admin_init'));

Now if I write it like this, it works with no issues, Warnings, or Fatal Errors (but requires PHP 5.2.3)...

add_action('admin_init', 'CTXPS_App::admin_init');

Written as an array, I get this...

Warning: call_user_func_array() [function.call-user-func-array]: First argument is expected to be a valid callback, was given in /var/www/vhosts/contextureintl.com/subdomains/plugintest/httpdocs/wp-includes/plugin.php on line 488

If I print_r($the_['function']) everywhere it appears in plugin.php, I see that the array now looks like this (which is not how it's written in the hook)...

array('CTXPS_App','admin_init',1)

So far I just haven't been able to figure out where that 1 is coming from.

Last edited 4 years ago by Veraxus (previous) (diff)

comment:5 @Veraxus4 years ago

  • Resolution set to worksforme
  • Status changed from reopened to closed

I loaded a fresh install of WordPress on a different server and there's no issues. There's definitely something wrong with the server, not WordPress.

I'll close this out unless I come up with something concrete to workaround.

Last edited 4 years ago by Veraxus (previous) (diff)
Note: See TracTickets for help on using tickets.