有许多与此相似的问题,但这有点不同,因为它涉及深层对象属性访问,而不仅仅是一个深度级别。
我们说我有一个包含字符串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};
答案 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