Есть ли вероятность, что я могу вывести информацию о параметрах типа PHP Closure? Рассмотрим этот пример:
<?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); } ?>
Я хочу оставить некоторую свободу для пользователя, чтобы он или она могли решить, какой способ лучше определить закрытие, которое будет зарегистрировано в моем диспетчере, – будет ли он принимать параметры в ассоциативном массиве или непосредственно как параметры Closure. Таким образом, диспетчеру необходимо вывести параметры пройденного Закрытия, чтобы определить, каким образом он должен называть это закрытие. Есть идеи?
Используйте reflection
, если вам нужно принимать решения, основываясь на структуре кода. В вашем случае ReflectionFunction
и ReflectionParameter
являются вашими друзьями.
<?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); } ?>
Вывод:
Giving individuals. Result: 5 10
Изменить определение для проверки:
$func = function(array $a){ echo implode(' ', $a); };
Вывод:
Giving array. Result: 5 10
Было бы намного проще, если бы ваша функция могла принимать разные типы ввода.
Например, в этом случае:
$foo = function() { $args = func_get_args(); if( is_array($args[0])) $args = $args[0]; echo $args[0]." ".$args[1]; }