PHP-间接修改重载属性 [英] PHP - Indirect modification of overloaded property
问题描述
我知道这个问题已经问过几次了,但是他们都没有真正的解决方法.也许我的具体情况有一个.
I know this question has been asked several times, but none of them have a real answer for a workaround. Maybe there's one for my specific case.
我正在构建一个映射器类,该映射器类使用魔术方法__get()
延迟加载其他对象.看起来像这样:
I'm building a mapper class which uses the magic method __get()
to lazy load other objects. It looks something like this:
public function __get ( $index )
{
if ( isset ($this->vars[$index]) )
{
return $this->vars[$index];
}
// $index = 'role';
$obj = $this->createNewObject ( $index );
return $obj;
}
在我的代码中,我这样做:
In my code I do:
$user = createObject('user');
$user->role->rolename;
到目前为止,该方法仍然有效. User
对象没有名为'role'的属性,因此它使用神奇的__get()
方法创建该对象,并从'role'对象返回其属性.
This works so far. The User
object doesn't have a property called 'role', so it uses the magic __get()
method to create that object and it returns its property from the 'role' object.
但是当我尝试修改'rolename'时:
But when i try to modify the 'rolename':
$user = createUser();
$user->role->rolename = 'Test';
然后它给了我以下错误:
Then it gives me the following error:
注意:重载属性的间接修改无效
不确定这是否仍然是PHP中的错误还是预期的行为",但是无论如何它都无法按照我想要的方式工作.对我来说,这确实是一个表演的终结者...因为我到底能如何改变延迟加载的对象的属性?
Not sure if this is still some bug in PHP or if it's "expected behaviour", but in any case it doesn't work the way I want. This is really a show stopper for me... Because how on earth am I able to change the properties of the lazy loaded objects??
仅当我返回包含多个对象的数组时,才会出现实际问题.
The actual problem only seems to occur when I return an array which contains multiple objects.
我添加了一个示例代码来重现该问题:
I've added an example piece of code which reproduces the problem:
您应该真正在PHP环境中运行此程序,并真正看到错误".但是这里确实发生了一些有趣的事情.
You should really run this in your PHP environment the really see the 'error'. But there is something really interesting going on here.
我尝试更改对象的属性,这使我注意到无法更改重载属性".但是,如果我在之后回显该属性,我会发现它实际上是DID更改了值……真的很奇怪……
I try to change the property of an object, which gives me the notice 'cant change overloaded property'. But if I echo the property after that I see that it actually DID change the value... Really weird...
推荐答案
很好,您给了我一些玩意儿
Nice you gave me something to play around with
运行
class Sample extends Creator {
}
$a = new Sample ();
$a->role->rolename = 'test';
echo $a->role->rolename , PHP_EOL;
$a->role->rolename->am->love->php = 'w00';
echo $a->role->rolename , PHP_EOL;
echo $a->role->rolename->am->love->php , PHP_EOL;
输出
test
test
w00
使用的类
abstract class Creator {
public function __get($name) {
if (! isset ( $this->{$name} )) {
$this->{$name} = new Value ( $name, null );
}
return $this->{$name};
}
public function __set($name, $value) {
$this->{$name} = new Value ( $name, $value );
}
}
class Value extends Creator {
private $name;
private $value;
function __construct($name, $value) {
$this->name = $name;
$this->value = $value;
}
function __toString()
{
return (string) $this->value ;
}
}
按要求提供新阵列支持
class Sample extends Creator {
}
$a = new Sample ();
$a->role = array (
"A",
"B",
"C"
);
$a->role[0]->nice = "OK" ;
print ($a->role[0]->nice . PHP_EOL);
$a->role[1]->nice->ok = array("foo","bar","die");
print ($a->role[1]->nice->ok[2] . PHP_EOL);
$a->role[2]->nice->raw = new stdClass();
$a->role[2]->nice->raw->name = "baba" ;
print ($a->role[2]->nice->raw->name. PHP_EOL);
输出
Ok die baba
修改后的类
abstract class Creator {
public function __get($name) {
if (! isset ( $this->{$name} )) {
$this->{$name} = new Value ( $name, null );
}
return $this->{$name};
}
public function __set($name, $value) {
if (is_array ( $value )) {
array_walk ( $value, function (&$item, $key) {
$item = new Value ( $key, $item );
} );
}
$this->{$name} = $value;
}
}
class Value {
private $name ;
function __construct($name, $value) {
$this->{$name} = $value;
$this->name = $value ;
}
public function __get($name) {
if (! isset ( $this->{$name} )) {
$this->{$name} = new Value ( $name, null );
}
if ($name == $this->name) {
return $this->value;
}
return $this->{$name};
}
public function __set($name, $value) {
if (is_array ( $value )) {
array_walk ( $value, function (&$item, $key) {
$item = new Value ( $key, $item );
} );
}
$this->{$name} = $value;
}
public function __toString() {
return (string) $this->name ;
}
}
这篇关于PHP-间接修改重载属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!