2011-08-25 55 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

相关问题