Silex PHP微框架基于自动类型提示进行回调注入。例如,在Silex中,可以提供具有任意参数的Closure参数,如:
$app->get('/blog/show/{postId}/{commentId}', function ($commentId, $postId) {
//...
});
$app->get('/blog/show/{id}', function (Application $app, Request $request, $id) {
//...
});
// following works just as well - order of arguments is not important
$app->get('/blog/show/{id}', function (Request $request, Application $app, $id) {
//...
});
我该怎么做?我对将参数类型作为字符串不感兴趣。我正在寻找一种“无字符串”的全自动解决方案。换句话说,
对于许多可能的论点:
$possible_arguments = [
new Class_A(),
new Class_B(),
new Class_C(),
new Another_Class,
$some_class
];
对于具有任意数量任意参数的闭包,只能包含上面定义的那些:
$closure = function (Class_B $b, Another_Class, $a) {
// Do something with $a and $b
};
我需要只获取匹配的参数才能用它们调用闭包:
// $arguments is now [$possible_arguments[1], $possible_arguments[3]]
call_user_func_array($closure, $arguments);
答案 0 :(得分:5)
我的猜测是使用反射。
http://php.net/manual/en/class.reflectionparameter.php
超级简单的例子:
function pre($var)
{
echo '<pre>' . var_export($var, true) . '</pre>';
}
interface TestInterface
{
}
class TestClass
{
public function __construct(TestInterface $testArg)
{
}
}
function TestFunc(TestInterface $testArg)
{
}
// for a class...
$className = 'TestClass';
$methodName = '__construct';
$argNumber = 0;
$ref = new ReflectionParameter([$className, $methodName], $argNumber);
pre($ref);
pre($ref->getClass());
// for a function...
$funcName = 'TestFunc';
$argNumber = 0;
$ref = new ReflectionParameter($funcName, $argNumber);
pre($ref);
pre($ref->getClass());
我在stackoverflow上发现的另一个问题可能是您问题的更好答案:PHP Reflection - Get Method Parameter Type As String
答案 1 :(得分:3)
确实他们正在使用Reflection
,特别是the ControllerResolver class。
如果您让我简化为只包含一个Closure
个案例且只包含对象类型参数:
$availableArguments = array($a, new B(), $c);
$arguments = array();
$reflection = new \ReflectionFunction($callback); // $callback is a Closure
foreach ($reflection->getParameters() as $param) {
if ($paramClass = $param->getClass()) {
foreach ($availableArguments as $proposedArgument) {
if ($paramClass->isInstance($proposedArgument)) {
$arguments[] = $proposedArgument;
break;
}
}
}
}
call_user_func_array($callback, $arguments);