4

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) {
    //...
});

どうすればいいですか?パラメータの型を文字列として取得することに興味はありません。「文字列なし」の完全自動ソリューションを探しています。言い換えると、

  1. 考えられる引数の数:

    $possible_arguments = [
        new Class_A(), 
        new Class_B(), 
        new Class_C(), 
        new Another_Class, 
        $some_class
    ];
    
  2. 任意の数の任意の引数を持つクロージャーの場合、上記で定義されたものを一度だけ含めることができます。

    $closure = function (Class_B $b, Another_Class, $a) {
        // Do something with $a and $b
    };
    
  3. クロージャーを呼び出すには、一致する引数のみを取得する必要があります。

    // $arguments is now [$possible_arguments[1], $possible_arguments[3]]
    call_user_func_array($closure, $arguments);
    
4

2 に答える 2

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

于 2012-12-20T08:44:20.327 に答える
3

実際、彼らはReflection特にControllerResolver クラスで を使用しています。

Closureオブジェクト型の引数を1 つだけ含めるように単純化するとしたら、次のようになります。

$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);
于 2012-12-20T09:06:57.973 に答える