0

以下の状況を想定します。メソッドでさまざまな引数リストを使用するクラス階層があり、子孫クラスごとに拡張される可能性があります。

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

class A {
    public function __invoke(){
        $arguments = implode(', ', func_get_args());

        echo __METHOD__, ' arguments: ', $arguments, PHP_EOL;
    }
}

class B extends A {
    public function __invoke(){
        //               ... some actions ...
        // call to parent method with current argument list
        //               ... some actions ...
    }
}
?>

このクラス階層がメソッドの固定引数で実装されている場合、目的を達成するために__invoke()何かを使用する可能性があります。parent::__invoke($a, $b, $c, $etc);しかし残念ながら、両方のクラスABいくつかの機能があり、さまざまな引数リストに依存しています。

さて、質問: どうすればその引数リストparent::__invoke()から呼び出して渡すことができますか?B::__invoke()

そして、ええ、もっと複雑にします。チェーンがさらに拡張される可能性があるため、親クラスの実際の名前に依存することはできません。

PS:これについてはどこかで言及したいと思います。

4

1 に答える 1

0

それを実装するには 2 つの方法がありますが、そのうちの 1 つは私には明らかですReflection

  1. ReflectionClassfrom クラスを作成しますA

  2. ReflectionClass::getParentClass()メソッドで反射に最も近い親を取得します。

  3. __invoke()親クラスのメソッド リフレクションをメソッドで取得しReflectionClass::getMethod()ます。

  4. method を使用して、関数ReflectionMethod::invokeArgs()で親メソッドを呼び出し、func_get_args()現在の引数リストを渡します。

ただし、この機能を使用して単一の関数呼び出しを行うのはやり過ぎ (!) かもしれないと考えています。したがって、私は別の方法であると考えられています: function を持つ古くて強力な関数call_user_func_array()get_parent_class()です。

  1. get_parent_class()関数で親クラスを取得します。

  2. 現在のメソッド名を取得します(__METHOD__定数を使用することを考えていましたが、常にメソッドが宣言されているクラスプレフィックスを示しています)__FUNCTION__

  3. メソッド map で呼び出し、2 番目の引数としてcall_user_func_array()渡します。func_get_args()


解決:

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

class A {
    public function __invoke(){
        $arguments = implode(', ', func_get_args());

        echo __METHOD__, ' arguments: ', $arguments, PHP_EOL;
    }
}

class B extends A {
    public function __invoke(){
        echo __METHOD__, ' actions', PHP_EOL;

        $method = array(get_parent_class($this), __FUNCTION__);
        $result = call_user_func_array($method, func_get_args());

        echo __METHOD__, ' actions', PHP_EOL;
    }
}

$test = new B();

$test(1, 2, 3);
?>

結果:

B::__invoke actions
A::__invoke arguments: 1, 2, 3
B::__invoke actions
于 2013-10-01T14:11:39.350 に答える