PHP使用__get来调用方法?

时间:2012-02-07 01:28:56

标签: php class delegation

我有一些PHP cruft我想委托方法。一个穷人的混合物。

基本上我想要以下内容:

<?php

class Apprentice
{
    public function magic() {
        echo 'Abracadabra!';
    }
}

class Sourcerer // I work magic with the source
{
    private $apprentice;

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

    public function __get($key) {
        if (method_exists($this->apprentice, $key)) {
            return $this->apprentice->{$key};
        }
        throw Exception("no magic left");
    }
}

$source = new Sourcerer();
$source->magic();
?>

不要抛出Fatal error: Call to undefined method Sourcerer::magic() in .../test__get.php

4 个答案:

答案 0 :(得分:9)

public function __call($name, $args) {
    if (method_exists($this->apprentice, $name)) {
        return $this->apprentice->$name($args);
    }
    throw Exception("no magic left");
}

ps:使用__call作为方法,因为__get仅适用于属性。 是的,最好使用call_user_func_array,否则将参数作为数组提供给magic函数。

return call_user_func_array(array($this->apprentice, $name), $args);

答案 1 :(得分:3)

  1. 要在apprentice上实际调用该方法,您必须实际调用它:

    return $this->apprentice->$key();
    
  2. 您正在使用$source->magic(),它不会调用__get方法。 __get用于$source->magic等变量访问,但$source->magic()是函数调用。如果你想要一个魔术方法来进行函数调用,那就是__call

答案 2 :(得分:2)

更像是__call而不是__get

class Sourcerer // I work magic with the source
{
    private $apprentice;

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

    public function __call($name, $arguments) {
        if (method_exists($this->apprentice, $name)) {
            return call_user_func_array(array($this->apprentice, $name), $arguments);
        }
        throw Exception("no magic left");
    }
}

答案 3 :(得分:1)

您的电话将改为:

$source = new Sourcerer();
$source->apprentice->magic();

另外,我相信__get()魔术方法适用于属性,而不适用于方法名称。

最后,在您的实际__get()定义中,语法错误:它应该是throw new Exception('message');。我还将其移至else子句,否则无论如何都会触发每个调用,因为它超出任何if / else或其他逻辑。