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

有两种方法可以实现,其中一种对我来说很明显:使用Reflection.

  1. ReflectionClass从类创建一个A

  2. 使用方法获取反射最近的父级ReflectionClass::getParentClass()

  3. 通过方法获取__invoke()父类的方法反射ReflectionClass::getMethod()

  4. 使用ReflectionMethod::invokeArgs()方法调用带有func_get_args()函数的父方法以传递当前参数列表。

但是,我在想,使用此功能进行单个函数调用可能有点矫枉过正(!)。所以我被认为是另一种方式:古老而强大call_user_func_array()的函数get_parent_class()function

  1. get_parent_class()获取带函数的父类;

  2. 用常量获取当前方法名(我想用__METHOD__常量,但它总是显示一个类前缀,方法被声明的地方)__FUNCTION__

  3. call_user_func_array()使用方法 map调用并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 回答