@MIKEk8

Как в PHP получить объект по пути из переменной?

$object; //объект в котором есть объект "a", в котором есть объект "b", в котором есть объект "c"
$path = 'a->b->c';
Как получить из $object объект "c" используя переменную $path ?

Сейчас делаю так
$path = explode('->', $path);
foreach ($path as $step) {
  $object = $object->$step ?? null;
}
return $object;
  • Вопрос задан
  • 743 просмотра
Пригласить эксперта
Ответы на вопрос 4
GeneMoss
@GeneMoss
void
$object = new Object; // Инициализация объекта, который содержит property «a»

$path = 'a->b->c';
$properties = explode('->', $path);

$getProperty = function($obj, $property) {
    // Тут какие-нибудь проверки на существование, на instanceof и т. п.
    return $obj->$property;
};

$result = array_reduce($properties, $getProperty, $object);

// $result -- это последний property в цепочке, т.е. -- «c»


UPD: Как я понял, автор хочет хранить пути доступа к узлам в XML-файле. Для этого проще использовать xpath и хранить строки вида '/a/b/c'.
$xml = new SimpleXMLElement('<xml><a><b><c>test</c></b></a></xml>');
$result = $xml->xpath('//a/b/c');
Ответ написан
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
эээ, как бэ $object->{$path} должно работать, просто конструкция говорит о проблемах с проектированием.
Ответ написан
@artem78
Немного изменил Ваш вариант, и у меня он работает:
function getPropertyByPath($object, $path) {
	$path = explode('->', $path);
	foreach ($path as $step) {
		if (is_object($object) && property_exists($object, $step)) {
			$object = $object->$step;
		} else {
			return null;
		}
	}
	return $object;
}


var_dump($object);
$path = 'a->b->c';
var_dump(getPropertyByPath($object, $path));

Результат:
class stdClass#1 (1) {
  public $a =>
  class stdClass#2 (1) {
    public $b =>
    class stdClass#3 (1) {
      public $c =>
      string(5) "12345"
    }
  }
}
string(5) "12345"
Ответ написан
BoShurik
@BoShurik
Symfony developer
Если есть возможность использовать сторонние компонтенты, то
$object = new \stdClass();
$a = new \stdClass();
$a->name = 'a';
$b = new \stdClass();
$b->name = 'b';
$c = new \stdClass();
$c->name = 'c';

$object->a = $a;
$a->b = $b;
$b->c = $c;

$path = 'a.b.c';
$propertyAccessor = \Symfony\Component\PropertyAccess\PropertyAccess::createPropertyAccessor();
var_dump($propertyAccessor->getValue($object, $path));
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы