Make WordPress Core

Opened 12 years ago

Closed 12 years ago

#22218 closed enhancement (duplicate)

Extra add_action() parameter

Reported by: dgwyer's profile dgwyer Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.4.2
Component: General Keywords: 2nd-opinion
Focuses: Cc:

Description

Unless I am missing something really obvious here, this ticket makes a lot of sense to me.

---

There have been many instances where I have wanted to optionally pass my own parameters to hook callback functions, that haven't been specified in the hooks do_actions() function call.

It would be hugely beneficial to also be able to pass in an array (say) as an extra parameter when using add_action(). Something like:

$extra_args = array( 'value1', 'value2', 'value3' );
add_action( $hook, $callback, $priority, $accepted_args, $extra_args );

Then, in the callback function the $extra_args array would be accessible as well as any $accepted_args parameters. Maybe make it easy to access by always making it the last parameter?

function my_callback($wp1, $wp2, $args) {
    //$args[0] = 'value1';
    //$args[1] = 'value2';
    //$args[2] = 'value3';
}
$extra_args = array( 'value1', 'value2', 'value3' );
add_action( 'some_hook', 'my_callback', 10, 2, $accepted_args, $extra_args );

Note: I know I can achieve the same thing using global vars, but I don't really want to define them unnecessarily when using a parameter would make more sense.

Change History (8)

#1 @scribu
12 years ago

  • Keywords 2nd-opinion added
  • Type changed from defect (bug) to enhancement

You could use a wrapper class:

class My_Functor {

  function __construct( $cb, $args ) {
    $this->cb = $cb;
    $this->args = $args;
  }

  function invoke() {
    $args = func_get_args();
    return call_user_func_array( $this->cb, array_merge( $args, $this->args ) );
  }
}

$instance = new My_Functor( 'my_callback', array( 'value1', 'value2', 'value3' ) );
add_action( 'some_hook', array( $instance, 'invoke' ) );

This way, we can keep add_action() blazing fast for the normal case.

Last edited 12 years ago by scribu (previous) (diff)

#2 @dgwyer
12 years ago

  • Summary changed from Extra add_action() Parameter to Extra add_action() parameter

That's a pretty cool workaround. Works well.

I would still like to see a simpler implementation route, but I guess it's more important to keep a critical function such as add_action() as lean and mean as possible!

Looking at your code the only thing I am not sure of is the line:

$args = func_get_args();

I assume the hook parameters specified in do_action() get placed into $args? If that's correct I'm unclear how this works. Any pointers would be appreciated. :)

Last edited 12 years ago by dgwyer (previous) (diff)

#3 @scribu
12 years ago

func_get_args() is a special PHP function: http://php.net/func_get_args

#4 follow-up: @dgwyer
12 years ago

Yep, I've used that function before.

I just can't see, in this case, how any parameters specified in do_actions() for a particular hook are passed to the invoke() method via:

array( new My_Functor( 'my_callback', $extra_args ), 'invoke' )

#5 follow-up: @nacin
12 years ago

As scribu said, we wouldn't want to add anything else to add_action(). It needs to be kept fast and light, and it should be clear what its purpose is. This conflates its purpose.

#6 in reply to: ↑ 4 @scribu
12 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

If you poke around in the code a little, you'll figure it out. :)

Anyway, closing.

#7 in reply to: ↑ 5 ; follow-up: @nofearinc
12 years ago

  • Resolution wontfix deleted
  • Status changed from closed to reopened

Replying to nacin:

As scribu said, we wouldn't want to add anything else to add_action(). It needs to be kept fast and light, and it should be clear what its purpose is. This conflates its purpose.

How about a decorator to add_action/filter? It could be a separate function that helps for the numerous cases when arguments are needed and won't alter the current behavior of add_action/add_filter.

#8 in reply to: ↑ 7 @SergeyBiryukov
12 years ago

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

Replying to nofearinc:

How about a decorator to add_action/filter? It could be a separate function that helps for the numerous cases when arguments are needed and won't alter the current behavior of add_action/add_filter.

That would be a duplicate of #22250.

Note: See TracTickets for help on using tickets.