views:

545

answers:

4

Hi,

I'm writing a construct in PHP where a parser determins which function to call dynamically, kind of like this:

// The definition of what to call
$function_call_spec = array( "prototype"  => "myFunction", 
                             "parameters" => array( "first_par"  => "Hello",
                                                    "second_par" => "World"));

// Dispatch
$funcPrototype = $function_call_spec["prototype"];
$funcPrototype(); // Here we call function 'myFunction'.

This is all fine and dandy. But now comes the next step, passing the parameters, which I don't really know if it's possible the way I want to do it. It never stops amazing me however what script languages can do these days, so here goes:

One could pass the parameters to the function like this:

// Here we call function 'myFunction' with the array of parameters.
$funcPrototype( $function_call_spec["parameters"] );

However, I want to declare 'myFunction' properly with clear arguments etc:

function myFunction( $first_par, $second_par )
{

}

The question then follows - Is there any way to pass parameters to a function dynamically simply by looping through the parameter array?

To clarify, I don't want to do it like this:

$funcPrototype( $function_call_spec["parameters"]["first_par"],
                $function_call_spec["parameters"]["second_par"]  );

Because this requires my code to statically know details about myFunction, which goes against the whole idea.

Instead I would want to do it in some way like this maybe:

// Special magic PHP function which can be used for invoking functions dynamically
InvokeFunction( $funcPrototype, $function_call_spec["parameters"] );

Which then results in myFunction being called and all parameters in the array gets passed to each individual parameter variable in the prototype.

Any comments are welcome.

Regards.

/R

PS: None of the code in this post has been tested for typos etc.

+5  A: 
call_user_func_array($funcPrototype, $function_call_spec["parameters"]);

You might want to create a wrapper that names the function to your preference, such as:

function InvokeFunction($function, $args = array()) {
    return call_user_func_array($function, (array)$args);
}

With this function you can call it in 3 different ways:

$return = InvokeFunction('doStuff');
$return = InvokeFunction('doStuff', $single_arg);
$return = InvokeFunction('doStuff', $multiple_args);
orlandu63
Thanks for the advice!
sharkin
+10  A: 

You should use call_user_func_array which can call any function or method and takes parameteres from an array.

Alternatively you can use ReflectionFunction::invokeArgs, but there's no benefit over call_user_func_array unless you already use this class for someting else (like checking whether function you call accepts appropriate number and types of arguments).

porneL
A: 

call_user_func_array() is the best choice if you don't need to enforce the contract, otherwise use ReflectionFunction.

A: 

http://us2.php.net/create_function

When you use create_function(), your arguments are not evaluated until runtime. Pretty sweet.

pretty dangerous :-)
sharkin