__get dons';Don’不要为了某个名字而工作两次


__get doesn't work twice for some name

我知道这是一个奇怪的设置,但我正在努力避免Yii非常喜欢的一些魔法。

class myActiveRecord extends CActiveRecord
{
    public function __get($name) {
        $method = 'get' . ucfirst($name);
        if(method_exists($this, $method)) {
            $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
            foreach($backtrace  as $b) {
                if($b['function'] == $method) {
                    return parent::__get($name);
                }
            }
            return $this->$method();
        }
        return parent::__get($name);
    }
}
class test extends myActiveRecords
{
    public function getParty()
    {
        return $this->party;
    }
}
$test = new test();
echo $test->party;

我希望如果Yii调用$test->party,它不会只查找属性,而是首先遍历我的getFunction(),即使我的getFunction只是返回属性。(在Yii中,属性从未定义为属性,而是始终通过__get()

当我调用$test->getParty()时,它就像一个符咒,然而当Yii进行$test->party时,它没有,会发生以下情况:

$this->方调用magic__get(),后者调用函数getParty()。但是当函数getParty再次调用$this->party时,magic函数不会被第二次调用,但我得到了一个未定义的属性错误。我有办法,但我不喜欢使用它,这就是这个功能:

function getParty()
{
    return self::__get('party');
}

我开始这样工作的原因是因为我喜欢get和set方法,当我看到公共属性被这样使用时,我会发抖,也因为我被非英语编写的遗留代码所困扰,所以我经常这样做,这确实很有魅力,只是当同一名称的神奇函数被调用两次时:

public function getParty()
{
    return $this->feest;
}

有人知道原因吗?还是我错了?

如果你想覆盖神奇的__get(),你应该在你的子类中这样做:

class test extends myActiveRecords
{
    //overrides myActiveRecords' __get()
    public function __get($name)
    {
        if ($name == 'party') return $this->$name;
        else return parent::__get($name);
    }
}

根据你发布的代码查看代码,我认为这解释了差异:http://pastebin.com/cxh9HMah

原因是这可能导致对__get()方法的无限调用。是的,你可能会加入一些逻辑来阻止它。但php选择不允许开发人员开枪打自己的脚。因此,一旦进入__get()方法,就不会再次调用它。