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
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
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.
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
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);