带有数组的PHP getter和setter

时间:2012-03-11 10:38:04

标签: php arrays getter-setter

如果我使用magic __set将值设置为private var,我怎样才能将var设置为数组?

我想到这样的事情,假装我有一个__get __set

的班级
$myclass->names = 'Name'; // Works
$myclass->names = array('n1'=>'Name1', 'n2' => 'Name2'); // works as well

//this does not work
$myclass->names['n1'] = 'Name1';
$myclass->names['n2'] = 'Name2';

这是我想要开始工作的最后两个例子。已经测试了各种方法,但无法弄明白。

4 个答案:

答案 0 :(得分:2)

它无效。 $class->arr['key']将执行getter。所以基本上,你的代码看起来是:

array('key' => 'value')['key'] = 'new value';

显然,什么也没做。如果您希望这样做,您必须将names声明为公共财产。

答案 1 :(得分:1)

此表达式将调用getter:

 $myclass->names['n1'] = 'Name1';
 ^^^^^^^^^^^^^^^
 needs to be get
                ^^^^^^^^^^^^^^^^
                assignment later

实现这项工作的唯一方法是一个非常简单的解决方法。通过让getter将引用返回到know数组,以下赋值可以正常工作。

 function & __get($name) {

     if (is_array($this->$name)) {
          return & $this->$name;
     }
     else ...
 }

所以,如果显着简化了您的API,那么这是明智的。

答案 2 :(得分:1)

您显然不会输出通知,否则您会收到错误

  

注意:间接修改重载属性Foo :: $ bar没有   效果

您尝试做的事情根本不可能。只有一种方法可以通过__get写入来接收数组,但这很可能不是你想要的。

<?php

class Foo {
    protected $bar = array();

    public function &__get($name) {
        return $this->$name;
    }

    public function __set($name, $value) {
        return $this->$name = $value;
    }
}

$foo = new Foo();
$foo->bar = array('a', 'b', 'c');
echo $foo->bar[0]; // output "a"
$foo->bar[0] = 'z'; // fires warning
echo $foo->bar[0]; // output "z"

// all fine, but here's the catch:
$t =& $foo->bar;
$t = array('y');
echo $foo->bar[0]; // output "y"

既然您已经了解了如何通过引用返回值可能会出现问题,那么您可能会对ArrayObject感兴趣。像

这样的东西
<?php

class Foo {
    protected $bar = array();

    public function __get($name) {
        return new ArrayObject(&$this->$name);
    }

    public function __set($name, $value) {
        return $this->$name = $value;
    }
}

$foo = new Foo();
$foo->bar = array('a', 'b', 'c');
echo $foo->bar[0]; // output "a"
$foo->bar[0] = 'z'; // fires warning
echo $foo->bar[0]; // output "z"

// all fine, and no catch
$t =& $foo->bar;
$t = array('y');
echo $foo->bar[0]; // still outputs "z"

答案 3 :(得分:0)

试试这段代码:

class Foo
{
    private $bar;

    public function __construct()
    {
        $this->bar = new ArrayObject(array());
    }

    public function __get($item)
    {
        if(property_exists($this, $item)) {
            return $this->$item;
        }
    }

    public function __set($item, $value)
    {
        if(property_exists($this, $item)) {
            $this->{$item} = $value;
        }
    }
}

$obj = new Foo();
$obj->bar['color'] = 'green';
foreach($obj->bar as $attribute => $value) {
    echo '<p>' . $attribute . ' : ' . $value . '</p>' . PHP_EOL;
}
// output => color : green