使用各种参数列表从子方法调用父方法


Call parent method from child method using various argument list

假设以下情况。有一些类层次结构,它在方法中使用各种参数列表,可以为每个后代类扩展。

<?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都有一些功能,依赖于各种参数列表。

现在,问题:如何从B::__invoke()调用parent::__invoke()并通过其参数列表?

而且,是的,我会让它更复杂:我不能依赖父类的实际名称,因为链可能会进一步扩展。

PS:我只是想在某处提到这一点,因为今天这件事几乎救了我的命。

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

  1. 从类A创建ReflectionClass;

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

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

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

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

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

  2. 获取当前方法名称(我想使用__METHOD__常量,但它总是显示一个类前缀,其中声明了方法(和__FUNCTION__常量;

  3. 使用方法映射调用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