PHP-间接修改重载属性 [英] PHP - Indirect modification of overloaded property

查看:161
本文介绍了PHP-间接修改重载属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这个问题已经问过几次了,但是他们都没有真正的解决方法.也许我的具体情况有一个.

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:

http://codepad.org/T1iPZm9t

您应该真正在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆