如何在php中访问名为变量(点表示法)的深层对象属性?

时间:2017-01-11 15:11:25

标签: php properties

有许多与此相似的问题,但这有点不同,因为它涉及深层对象属性访问,而不仅仅是一个深度级别。

我们说我有一个包含字符串foo.bar的变量。

$user = new User();
$user->foo = new Foo();
$user->foo->bar = "Hello World";

$variable = "foo.bar"

我想通过使用$user->foo->bar来回应$variable

echo $user->foo->bar

这是我到目前为止所尝试的但没有成功(它说 NULL ):

$value = str_replace(".", "->", $value);
echo $user->{$value};

6 个答案:

答案 0 :(得分:9)

使用变量属性表示法($o->$p减少对象路径非常容易:

$path = 'foo.bar';
echo array_reduce(explode('.', $path), function ($o, $p) { return $o->$p; }, $user);

这很容易变成一个小辅助函数。

答案 1 :(得分:1)

@deceze帖子增加了一点改进。

这允许处理你需要通过数组的情况。

$path = 'foo.bar.songs.0.title';
echo array_reduce(explode('.', $path), function ($o, $p) { return is_numeric($p) ? $o[$p] : $o->$p; }, $user);

编辑:

如果你有PHP 7+,那么如果属性的名称输入错误或者它不存在,以下内容将安全地返回null。

$path = 'foo.bar.songs.0FOOBAR.title';
echo array_reduce(explode('.', $path), function ($o, $p) { return is_numeric($p) ? ($o[$p] ?? null) : ($o->$p ?? null); }, $user);

答案 2 :(得分:0)

我发布这个作为对答案(How to write getter/setter to access multi-level array by key names?)的赞美,它对数组做同样的事情。

通过$path创建explode()数组(或添加到函数中),然后使用引用。

$path = explode('.', $variable);

吸气剂

function get($path, $object) {
    $temp = &$object;

    foreach($path as $var) {
        $temp =& $temp->$var;
    }
    return $temp;
}

$value = get($path, $user);

当然是邪恶的eval(),不推荐:

$value = str_replace('.', '->', $variable);
eval("echo \$user->$value;");

答案 3 :(得分:0)

您可以通过Composer使用this JSON package

composer require machitgarha/json

例如:

$userJson = new MAChitgarha\Component\JSON(new User());

$userJson->set("foo", new Foo());
$userJson->set("foo.bar", "Hello World");

$userJson->get("foo.bar"); // Hello World 

答案 4 :(得分:0)

我写了一个递归算法来查找属性的所有值。

    public function findAttributeFromJson($json,$attributeFind,$assignAttribute)
{
    if(!is_array($json)) return $assignAttribute;

    $properties = array_keys($json);

    foreach ($properties as $value) {
        if($value === $attributeFind)
        {
            $assignAttribute[count($assignAttribute)] = $json[$value];
        }
        $assignAttribute = $this->findAttributeFromJson($json[$value],$attributeFind,$assignAttribute);
    }
    return $assignAttribute;
}

并使用它

        $arrResult = array();
        $arrResult = $this->findAttributeFromJson($arrFind,$properties,$arrResult );

答案 5 :(得分:-1)

没有简单的方法可以做到。

幸运的是,很多人希望这样做,所以有支持它的库,比如Symfony的PropertyAccessor:

http://symfony.com/doc/current/components/property_access.html