0

给定扩展类 B 的类 A,如何调用类 A 的 __call 函数覆盖从父类继承的匹配函数?

考虑这个简化的例子:

class A
{
    public function method_one()
    {
        echo "Method one!\n";
    }
}
class B extends A
{
    public function __call($name, $args)
    {
        echo "You called $name!\n";
    }
}
$b = new B();
$b->method_one();

当我运行它时,我得到了输出Method one!。我想得到输出You called method_one!

那么,如何让子类的魔法方法覆盖父类定义的方法呢​​?

我需要扩展对象,因为我需要访问 A 中的受保护方法,但我想将所有公共方法引导到我自己的 __call 处理程序中。有没有办法做到这一点?

4

3 回答 3

0

根据马克贝克的评论,这是我实际使用的答案。

通过将我想要访问其方法的类的对象作为变量,我可以使用 ReflectionMethod 来访问它的任何方法,就像我在扩展它一样,但 __call 仍然可以捕获其他所有内容。所以我想通过的任何方法,我都可以通过这样的方式:

public function __call($name, $args)
{
    $method = new ReflectionMethod($this->A, $name);
    $method->setAccessible(true);
    return $method->invokeArgs($this->A, $args);
}

或者在我的情况下,像这样的完整课程:

class B
{
    private $A;

    public function __construct()
    {
        $this->A = new A();
    }

    public function __call($name, $args)
    {
        echo "You called $name!\n";
    }

    public function protected_method()
    {
        $method = new ReflectionMethod($this->A, 'protected_method');
        $method->setAccessible(true);
        return $method->invoke($this->A, $args);
    }
}
于 2013-05-01T10:57:58.780 回答
0

尝试这个

 class A1
{
    protected function method_one()
    {
       echo "Method one!\n";
    }
}
class B1
{
    private $A;
    public function __construct()
    {
       $this->A = new A1;
    }
    public function __call($name, $args)
   {
      $class = new ReflectionClass($this->A);
      $method = $class->getMethod($name);
      $method->setAccessible(true);
      //return $method;
      echo "You called $name!\n";
      $Output=$method->invokeArgs($this->A, $args);
      $method->setAccessible(false);
      return $Output;
  }
 }

$a = new B1;
$a->method_one("");
于 2013-05-01T10:37:09.840 回答
0

所以,我找到了一种方法,它包括创建一个中间类来公开我需要的受保护方法,同时仍然对公共方法使用 __call。这行得通,但我真的不喜欢扩展一个类只是为了公开一个受保护的方法的想法......不过,有人可能会觉得它很有用,所以我想分享一下:

class A
{
    public function method_one()
    {
        echo "Method one!\n";
    }
    protected function protected_method()
    {
        echo "Accessible!\n";
    }
}
class A_accessor extends A
{
    public function publicise()
    {
        $args = func_get_args();
        return call_user_func_array(array($this, array_shift($args)), $args);
    }
}
class B
{
    private $A;

    public function __construct()
    {
        $this->A = new A_accessor();
    }

    public function __call($name, $args)
    {
        echo "You called $name!\n";
    }

    public function protected_method()
    {
        return $this->A->publicise('protected_method');
    }
}
$b = new B();
$b->method_one();
$b->protected_method();
于 2013-05-01T10:39:23.877 回答