2014-10-01 17 views
2

我知道這是一個奇怪的設置,但我試圖避免一些神奇的Yii非常喜歡。__get不能爲某個名字工作兩次

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的調用$測試 - >黨不只是看的屬性,但首先通過我的getFunction(),即使我的getFunction剛剛返回屬性。在Yii中,屬性永遠不會被定義爲一個屬性,但總是通過__get()來處理。但是當Yii執行這個$ test-> party時不會發生以下情況:

$ this-> party calls magic __get(),它調用函數getParty()。但是,當函數getParty再次執行$ this-> party時,魔術函數不會被稱爲。第二次,但我得到一個未定義的屬性錯誤 我有一個辦法解決,但我不喜歡使用它,這就是這個函數:

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

我開始這樣工作的原因是因爲我喜歡獲取和設置方法,當我看到像這樣的公共屬性時,我會感到不適,同時也因爲我遺留的遺留代碼不是用英語寫的,所以我經常這樣做這個工作就像一個魅力,而不是當同一個名字的魔法功能被稱爲兩次時:

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

有沒有人知道原因?還是我錯了?

回答

0

原因是這可能會導致無限呼叫__get()方法。是的,你可能會加入一些會阻止它的邏輯。但PHP選擇不允許開發人員在腳下自拍。出於這個原因,一旦進入__get()方法,它不會再被調用。

+0

在這裏,我認爲PHP是在腳下射擊自己。 但是,謝謝你確認這是它應該按照PHP工作的方式。我會堅持我以前的「解決方案」,並明確地調用__get方法。 – tmas 2014-10-01 11:43:33

1

如果你想覆蓋的魔法__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

+0

關鍵是不必爲每一個單獨的論點都這樣做,那麼我更喜歡我的「解決方案」。 – tmas 2014-10-01 11:41:42

相關問題