An implementation where parameters are submitted by their name.
This function calls class functions, class methods, functions and anonymous functions.
/**
* Calls a method, function or closure. Parameters are supplied by their names instead of their position.
* @param $call_arg like $callback in call_user_func_array()
* Case1: {object, method}
* Case2: {class, function}
* Case3: "class::function"
* Case4: "function"
* Case5: closure
* @param array $param_array A key-value array with the parameters
* @return result of the method, function or closure
* @throws \Exception when wrong arguments are given or required parameters are not given.
*/
function call_user_function_named_param($call_arg, array $param_array)
{
$Func = null;
$Method = null;
$Object = null;
$Class = null;
// The cases. f means function name
// Case1: f({object, method}, params)
// Case2: f({class, function}, params)
if(is_array($call_arg) && count($call_arg) == 2)
{
if(is_object($call_arg[0]))
{
$Object = $call_arg[0];
$Class = get_class($Object);
}
else if(is_string($call_arg[0]))
{
$Class = $call_arg[0];
}
if(is_string($call_arg[1]))
{
$Method = $call_arg[1];
}
}
// Case3: f("class::function", params)
else if(is_string($call_arg) && strpos($call_arg, "::") !== FALSE)
{
list($Class, $Method) = explode("::", $call_arg);
}
// Case4: f("function", params)
else if(is_string($call_arg) && strpos($call_arg, "::") === FALSE)
{
$Method = $call_arg;
}
// Case5: f(closure, params)
else if(is_object($call_arg) && $call_arg instanceof \Closure)
{
$Method = $call_arg;
}
else throw new \Exception("Case not allowed! Invalid Data supplied!");
if($Class) $Func = new \ReflectionMethod($Class, $Method);
else $Func = new \ReflectionFunction($Method);
$params = array();
foreach($Func->getParameters() as $Param)
{
if($Param->isDefaultValueAvailable()) $params[$Param->getPosition()] = $Param->getDefaultValue();
if(array_key_exists($Param->name, $param_array)) $params[$Param->getPosition()] = $param_array[$Param->name];
if(!$Param->isOptional() && !isset($params[$Param->getPosition()])) die("No Defaultvalue available and no Value supplied!\r\n");
}
if($Func instanceof \ReflectionFunction) return $Func->invokeArgs($params);
if($Func->isStatic()) return $Func->invokeArgs(null, $params);
else return $Func->invokeArgs($Object, $params);
}
//Test code:
function func($arg1, $arg2 = "Jane")
{
return $arg1 . "," . $arg2;
}
class tc1
{
public static function func1($Arg1, $Arg2 = "HH")
{
return $Arg1 . " " . $Arg2;
}
}
$func2 = function($a1, $a2)
{
return "a1:" . $a1 . ", a2:" . $a2;
};
$ret = call_user_function_named_param('func', array("arg1"=>"Hello", "arg2"=>"Joe"));
echo "Call Return:" . print_r($ret, true) . PHP_EOL;
$ret = call_user_function_named_param(array(new tc1(), 'func1'), array("Arg1"=>"Hello", "Arg2"=>"Joe"));
echo "Call2 Return:" . print_r($ret, true) . PHP_EOL;
$ret = call_user_function_named_param($func2, array("a1"=>"Hello", "a2"=>"Joe"));
echo "Call3 Return:" . print_r($ret, true) . PHP_EOL;