2

我想以某种方式隐藏父方法,以便为父类上定义的方法调用子类的 __call 魔术方法。例如:

class C {
  function foo() { echo "foo\n"; }
}

class D extends C {
  function __call( $method, $args ) { echo "called $name\n"; }
}

$d = new D();
$d->foo();

// desired result: called foo
// actual result: foo

我已经检查了 rename_function 和 override_function 但它们不适用于方法。ReflectionMethod 有一个我尝试过的 setAccessible 方法,但这似乎只有在您使用 ReflectionMethod 实例来调用该方法时才有效。

背景:试图拥有一个可以利用 PHP 类型检查的 RPC 代理类。因此,如果我有一个 RPCFoo,我可以使用类型提示或 instanceof 来强制执行类型,以便我可以检查($RPCFoo 实例 Foo)。

编辑:基类应该能够在没有代理的情况下按原样使用。这样代理可以成为系统配置的一部分,而不是代码。想想多台服务器都具有相同的代码库,但能够为每个服务器分配某些任务。如果本地服务器不处理请求的服务,类加载器将返回一个代理而不是基类。如果本地服务器确实处理了请求的服务,它将返回基类。

再次编辑:提供的方法是可行的,但对 IDE 和反射隐藏了基类的设计接口。我试图使代理实现干净,以便只需从基类继承并实现代理接口。为了维护基类接口,代理开发者必须重新实现所有公共和受保护的方法来进行远程调用。然后,当基类中的某些内容更新时,代理也必须更新。最后,我想我只是去编写一个使用反射的代理生成器为开发人员做这件事。

感谢您的回复!

4

3 回答 3

2

foo您必须将对方法的访问权限设置为private

class C {
    private function foo() {
        echo "foo\n";
    }
    public function __call($method, $args) {
        if(is_callable(array($this,$method))) {
            return call_user_func_array(array($this,$method), $args);
        } else {
            trigger_error("Call to undefined method '{$method}'");
        }
    }
}
于 2012-02-05T18:22:57.070 回答
0

我知道这个问题有点老了,但我得到了它的工作,所以我把它贴在这里帮助面临同样问题的人。

我用魔术 __call() 方法覆盖父方法的解决方案:

public function foo($p1, $p2, $p3)
{
    if (get_class($this) == __CLASS__) {
        /* Do stuff here */
    } elseif (method_exists($this, '__call')) {
        return call_user_func_array([$this, '__call'], ['foo', func_get_args()]);
    }

    return false;
}

唯一的限制是父类本身不能有一个神奇的 __call() 方法,否则它会从父类而不是扩展子类调用 __call() 方法。

于 2014-10-07T15:44:20.040 回答
0
class C {

    public function __call($method, $args) {
        return call_user_func_array(array(__CLASS__ ,$method), $args);
    }

    protected function foo() { echo "foo<br />"; }
}

class D extends C {
    function __call( $method, $args ) { echo "called $method<br/>"; }
}

$d = new D();
$d->foo();

$c = new C();
$c->foo();
于 2012-02-05T19:48:17.793 回答