2014-01-22 64 views
0

当你有下面的代码添加。动态私有财产为对象

有没有可能做添加动态私有属性?或者在运行时使用Reflection将它们设置为私有?

我的__set方法需要每次有人试图在我的班级中设置任何属性时调用。我可以将所有属性设置为私有属性,但是,我拥有在此类中动态添加的属性,并且在自动添加属性时,它具有公共可见性。

这可以防止调用__set方法。如何使动态属性在接收值时调用__set

实际上,ReflectionProperty类中有一个名为setAccessible()的方法。我会做这个方法的反面。

+0

简短的回答,没有。长的答案,你可能能够使用反射来改变属性的范围..但反射不应该像那样使用,除非你正在调试或单元测试。 –

+0

你到底想干什么? –

+0

@FabienWarniez刚刚为这个问题增加了真实的信息。 –

回答

3

在当前版本的PHP中,这似乎不可行。

虽然ReflectionProperty::setAccessible()确实采取一个布尔参数,它所做的更改只允许反射本身访问/不访问该值。它实际上并没有改变实际财产的可访问性。

作为一个哈克的解决办法,以保持动力性能的私人,考虑具有不实际存在于一个专门的专用阵列您__set存储属性。示例代码:

class Test { 

    private $foo; 
    public $bar; 
    private $_properties; 

    public function __get($prop) { 
     if(property_exists($this, $prop)) 
      return $this->$prop; 
     if(array_key_exists($prop, $this->_properties)) 
      return $this->_properties[$prop]; 
    } 

    public function __set($prop, $value) { 
     if(!property_exists($this, $prop)) { 
      $this->_properties[$prop] = $value; 
      echo 'SetDynamic: ', $prop, "\n"; 
      return; 
     } 
     $this->$prop = $value; 
     echo 'Set: ', $prop, "\n"; 
    } 

} 

从PHP交互提示运行:

 
php > $t = new Test; 
php > $t->foo = 1; 
Set: foo 
php > $t->foo = 2; 
Set: foo 
php > $t->bar = 1; 
php > $t->testorama = 1; 
SetDynamic: testorama 
php > $t->testorama = 2; 
SetDynamic: testorama 

虽然这将确保外部访问总是经过您的__get__set方法,它为内部问题使用,因为你现在总是有两个地方检查动态属性。这就是为什么这是一个骇人的解决方法,而不是一个真正的解决方案。

+0

虽然这可能不是最好的解决方案,但它完全按照我的需要工作。我不能直接在类中调用这些属性,它们只能在外部使用,并且不能从类内部访问。此外,现在我看到我误解了'setAccessible()'方法的概念。谢谢! –