问题
Below is the code that I'm working with.
function my_tab( $tabs ) {
// the following array will be created dynamically
$colors = array("red", "white", "blue");
foreach ($colors as $value) {
$tabs[$value] = array(
'name' => $value
);
// start creating functions
function content_for_[$value]() {
echo "this is the " .$value. " tab";
}
// stop creating functions
add_action('content_for_'.$value, 'content_for_'.$value);
}
return $tabs;
}
As you can see, I have an array that's created dynamically. For each color
I need to create a function
. These functions are tied into hooks
and the function names have to exist
. So far, everything I've tried for the past 6 hours results in an error similar to:
"call_user_func_array() expects parameter 1 to be a valid callback, function 'content_for_green' not found or invalid function name"
回答1:
If you're using PHP >= 5.3, you can use anonymous functions, e.g.
add_action( 'content_for_' . $value, function() use ( $value ) {
echo "this is the " . $value . " tab";
}
);
With use
keyword are allowing the anonymous function to capture the variables from current scope (e.g. $value
in your case).
回答2:
You most certainly don't want to do that, this is horrible practice. Using closures, as vitozev advises, is sensibly less ugly, but is still hard to maintain voodoo magic.
Instead, just add a parameter to your callback, e.g. by expanding your existing parameter array:
function content_for_color_callback($args) {
echo 'this is the ' . $args['color'] . ' tab';
}
Simply register the hook:
add_action('content_for_color', 'content_for_color_callback');
... and pass color
as a standard parameter, :
// do not do this
do_action("content_for_{$nav}", $args);
// do this instead
$args['color'] = $nav;
do_action('content_for_color', $args);
One of the many advantages with this approach is that you have a much less room for obscure errors. For example, imagine someone feels like calling a non-existing content_for_bazinga()
function. With your approach, you would get an obscure
Call to undefined function content_for_bazinga()
Compare with:
function content_for_color_callback($args) {
$color = $args['color'];
if( !colorIsValid($color)) {
throw new Exception("There is no such tab: $color");
}
echo "This is the $color tab";
}
来源:https://stackoverflow.com/questions/33635594/creating-a-function-name-on-the-fly-dynamically-php