Deducing PHP Closure parameters

2019-04-24 11:05发布

Is there any chance that I can deduce PHP Closure parameters type information? Consider this example:

<?php

$foo = function(array $args)
{
    echo $args['a'] . ' ' . $args['b'];
};

$bar = function($a, $b)
{
    echo $a . ' ' . $b;
};

$closure = /* some condition */ $foo : $bar;

if(/* $closure accepts array? */)
{
    call_user_func($closure, ['a' => 5, 'b' => 10]);
}
else
{
    call_user_func($closure, 5, 10);
}

?>

I want to leave some freedom for user so he or she could decide which way is better to define a Closure that will be registered in my dispatcher - will it accept parameters in associative array or directly as Closure parameters. So, dispatcher need to deduce parameters of the passed Closure to determine which way should it call this Closure. Any ideas?

标签: php closures
2条回答
姐就是有狂的资本
2楼-- · 2019-04-24 11:46

It would be much easier to have your function be able to accept different types of input.

For instance, in this case:

$foo = function() {
    $args = func_get_args();
    if( is_array($args[0])) $args = $args[0];
    echo $args[0]." ".$args[1];
}
查看更多
该账号已被封号
3楼-- · 2019-04-24 11:57

Use reflection, if you need to make decisions, based on code structure. In your case ReflectionFunction and ReflectionParameter are your friends.

<?php
header('Content-Type: text/plain; charset=utf-8');

$func = function($a, $b){ echo implode(' ', func_get_args()); };

$closure    = $func;
$reflection = new ReflectionFunction($closure);
$arguments  = $reflection->getParameters();

if($arguments && $arguments[0]->isArray()){
    echo 'Giving array. Result: ';
    call_user_func($closure, ['a' => 5, 'b' => 10]);
} else {
    echo 'Giving individuals. Result: ';
    call_user_func($closure, 5, 10);
}
?>

Output:

Giving individuals. Result: 5 10

Change definition to test:

$func = function(array $a){ echo implode(' ', $a); };

Output:

Giving array. Result: 5 10
查看更多
登录 后发表回答