Как я могу получить доступ к глубокому объекту, названному как переменная (точечная нотация) в php?

Есть много вопросов, подобных этому, однако это немного отличается, поскольку речь идет о доступе к объектам с глубокими объектами, а не только к одному уровню глубины.

Допустим, у меня есть переменная, содержащая строку foo.bar .

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

Я бы хотел, чтобы echo $user->foo->bar , используя $variable :

 echo $user->foo->bar 

Это то, что я пробовал до сих пор, но без успеха (он говорит NULL ):

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

Очень просто уменьшить путь к объекту, используя переменную обозначение свойства ( $o->$p ):

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

Это легко можно было бы превратить в небольшую вспомогательную функцию.

Я размещаю это как комплимент ответа ( как написать getter / setter для доступа к многоуровневому массиву по именам ключей? ), Который делает то же самое для массивов.

Создайте массив $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;"); 

Нет простого способа сделать это.

К счастью, многие люди хотят это сделать, поэтому есть библиотеки, которые его поддерживают, например, PropertyAccessor от Symfony:

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