There are many questions similar to this, however this is slightly different since it's about deep object property access, not just one level of depth.
Let's say I have a variable containing the string foo.bar
.
$user = new User();
$user->foo = new Foo();
$user->foo->bar = "Hello World";
$variable = "foo.bar"
I would like to echo $user->foo->bar
by making use of $variable
:
echo $user->foo->bar
This is what I have tried so far but with no success (it says NULL ):
$value = str_replace(".", "->", $value);
echo $user->{$value};
It is very easy to reduce the object path using variable property notation ( $o->$p
):
$path = 'foo.bar';
echo array_reduce(explode('.', $path), function ($o, $p) { return $o->$p; }, $user);
This could easily be turned into a small helper function.
A little improvement added to @deceze post.
This allow handling cases where you need to go through arrays also.
$path = 'foo.bar.songs.0.title';
echo array_reduce(explode('.', $path), function ($o, $p) { return is_numeric($p) ? $o[$p] : $o->$p; }, $user);
Edit:
And if you have PHP 7+, then the following will safely return null if a property's name is mistyped or if it doesn't exist.
$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);
There is no easy way to do it.
Fortunately though, lots of people want to do this, so there's libraries that support it, like Symfony's PropertyAccessor:
http://symfony.com/doc/current/components/property_access.html
I am posting this as a compliment to an answer ( How to write getter/setter to access multi-level array by key names? ) that does the same for arrays.
Create the $path
array via explode()
(or add to the function), then use references.
$path = explode('.', $variable);
function get($path, $object) {
$temp = &$object;
foreach($path as $var) {
$temp =& $temp->$var;
}
return $temp;
}
$value = get($path, $user);
And of course the evil eval()
, not recommended:
$value = str_replace('.', '->', $variable);
eval("echo \$user->$value;");
You can use my JSON package using Composer:
composer require machitgarha/json
For example:
$userJson = new MAChitgarha\Component\JSON(new User());
$userJson->set("foo", new Foo());
$userJson->set("foo.bar", "Hello World");
$userJson->get("foo.bar"); // Hello World
I have written a recursive algorithm for finding all the values of properties.
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;
}
And use it
$arrResult = array();
$arrResult = $this->findAttributeFromJson($arrFind,$properties,$arrResult );
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.