如果我使用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';
这是我想要开始工作的最后两个例子。已经测试了各种方法,但无法弄明白。
答案 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