当前位置: 首页 > 面试题库 >

PHP-间接修改重载属性

舒仲渊
2023-03-14
问题内容

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

我正在构建一个映射器类,该映射器类使用magic方法__get()来延迟加载其他对象。看起来像这样:

public function __get ( $index )
{
    if ( isset ($this->vars[$index]) )
    {
        return $this->vars[$index];
    }

    // $index = 'role';
    $obj = $this->createNewObject ( $index );

    return $obj;
}

在我的代码中,我这样做:

$user = createObject('user');
$user->role->rolename;

到目前为止,该方法有效。该User对象没有名为“ role”的属性,因此它使用magic __get()方法创建该对象,并从“
role”对象返回其属性。

但是当我尝试修改’rolename’时:

$user = createUser();
$user->role->rolename = 'Test';

然后它给了我以下错误:

注意:间接修改重载属性无效

不知道这是否仍然是PHP中的某个bug还是“预期的行为”,但是无论如何它都不符合我想要的方式。对我来说,这确实是一个表演的终结者。。。因为我到底能如何改变延迟加载对象的属性?

编辑:

当我返回包含多个对象的数组时,似乎只会出现实际问题。

我添加了一个示例代码来重现该问题:

http://codepad.org/T1iPZm9t

您应该在PHP环境中真正运行此程序,才能真正看到“错误”。但是这里确实发生了一些有趣的事情。

我尝试更改对象的属性,这使我注意到“无法更改重载属性”。但是如果我在之后回显该属性,我会发现它实际上是DID更改了值…真的很奇怪…


问题答案:

很好,你给了我一些玩的东西

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 ;
    }   
}


 类似资料:
  • 修改属性(命令)是用于修改或更新特定类的属性的命令。修改属性意味着修改表格的字段。 在本章中,将学习如何更新属性。 以下语句是命令的基本语法。 以下是有关上述语法中选项的详细信息。 - 定义属性所属的类。 - 定义您想要更新的属性。 - 定义要更新的属性的属性。 - 定义您想要在属性上设置的值。 下表定义了用于更改属性的属性列表。 属性 类型 描述 LINKEDCLASS 字符串 定义链接的类名称

  • 除了在构造函数中指定材质,在网格被创建后,也能对材质进行修改: 例5.2.1 var material = new THREE.MeshLambertMaterial({ color: 0xffff00 }); var geometry = new THREE.CubeGeometry(1, 2, 3); var mesh = new THREE.Mesh(geometry, materi

  • 本文向大家介绍python如何修改文件时间属性,包括了python如何修改文件时间属性的使用技巧和注意事项,需要的朋友参考一下 1、获取文件的创建、修改、访问时间  2、更改文件的修改、访问时间(创建时间没查到怎么修改,暂时不记录)  3、放在同一个py方便直接复制使用  4、补充修改文件的创建时间 以上就是python如何修改文件时间属性的详细内容,更多关于python修改文件时间属性的资料请关

  • 问题内容: 如何修改/设置两个值? 主机IP地址 value =“ 0x00010a248921” “供应商ID” 值=“ 11” 我尝试访问失败, 目标: 我更希望看到一个lxml.objectify与一个Xpath解决方案,但我将接受其他基于lxml的解决方案。 文件小于100kB,因此速度/ RAM无关紧要。 问题答案:

  • 问题内容: 我想要一个可以修改响应主体的中间件功能。 这是用于快递服务器。 就像是: 我不明白该听什么。任何帮助或文档将不胜感激。 问题答案: 您不需要听任何事件。只要做到 而之后你把它的路由器。这样,在执行完所有路线后,您可以修改车身