Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deducing PHP Closure parameters

Tags:

closures

php

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?

like image 253
nyan-cat Avatar asked Oct 05 '13 14:10

nyan-cat


2 Answers

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
like image 101
BlitZ Avatar answered Sep 30 '22 20:09

BlitZ


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];
}
like image 25
Niet the Dark Absol Avatar answered Sep 30 '22 22:09

Niet the Dark Absol