2011-08-25 50 views
2

好了,這裏是我的Properties基類的一個片段,即在大多數在我的應用程序的類的擴展:爲什麼直接訪問數組不可能使用magic __set()方法?

class Properties { 
    protected $properties_arr = array(); 

    /** 
    * Magic function to be able to access the object's properties 
    * @param string $property 
    */ 
    public function __get($property) { 
     if (array_key_exists($property, $this->properties_arr)) { 
      return $this->properties_arr[ $property ]; 
     } 

     return $this->getUndefinedProperty($property); 
    } 

    /** 
    * Magic function to be able to access the object's properties 
    * @param string $property 
    * @param mixed $value 
    */ 
    public function __set($property, $value) { 
     if (property_exists($this, $property)) { 
      $this->setProtectedProperty($property); 
     } 

     $this->properties_arr[ $property ] = $value; 
    } 

這是很基本的,有什麼不妥的,但我運行到一個我以前遇到過幾次的問題,就是你無法通過__get方法對array屬性執行某些操作。

這樣做,例如:

$MyClass = new Properties(); 
$MyClass->test = array(); 
$MyClass->test['key'] = 'value'; 

你所期望的$MyClass->test陣列包含一個項目,但它仍然是一個空的數組!現在我知道我可以通過僅僅分配一個已經在其中的項目來解決它,但我真的很想知道這是爲什麼(以及是否有更好的解決方案)。

謝謝!

+0

什麼是'屬性:: setProtectedProperty($ var)'? – binaryLV

+0

只是一個引發'Exception'的內部方法,但可以由子類重寫以定製行爲。你認爲這可能與問題有關嗎?在遇到問題的課堂上,我不會壓倒它。 – Rijk

+0

也許不,不應該是個問題。請參閱@彼得的答案,它適用於我。沒有它,我得到了PHP錯誤「*注意:重載屬性的間接修改Test :: $ foo沒有任何作用*」(你是否啓用了錯誤報告?) – binaryLV

回答

4

請參閱PHP Accessor functions and arrays

問題可能是您需要使__get()方法返回引用。

+0

是的;估計就是這樣。另請參閱[此錯誤](https://bugs.php.net/bug.php?id=39449)瞭解一些歷史記錄。 @Rijk,我認爲你的代碼應該在你的數組訪問中拋出一個警告 - 你是否打開了錯誤報告? –

+0

啊對,現在我明白了!我已經在PHP.net的評論中找到了這個解決方案,但是作者沒有在SO上的帖子中解釋它。對我來說問題是,這會觸發一個「只有變量引用應該被引用返回」,因爲有條件的'getUndefinedProperty()'return .. :( – Rijk

+0

@Matt:我當然可以,一切都包括Notices。 t觸發警告 - 你能告訴我你期望的錯誤嗎? – Rijk

0

這是因爲您還需要重寫__isset magic方法來檢查數組索引是否存在。

+0

嗯,我剛剛實現了一個'__isset()'方法,它似乎根本不被調用?這不是用來重寫'isset($ Object-> property)'行爲的嗎? – Rijk

+0

這就像:public function __isset($ key){return isset($ this-> tab [$ key]); }。在和你做幾乎相同的事情時,我遇到了這個問題,這個解決方案成了訣竅。 Yup; – Whiskas

相關問題