Как связать функции вызова цепочки с помощью строки, содержащей эту цепочку в PHP


У меня есть цепной вызов примерно так:

$object->getUser()->getName();

Я знаю, что могу использовать строку для вызова функции для объекта:

$functionName = 'getUser';
$object->$functionName() or call_user_func(array($object, functionName))

Мне было интересно, можно ли сделать то же самое для вызова по цепочке? Я пытался сделать:

$functionName = 'getUser()->getName';
$object->functionName();

Но я получаю сообщение об ошибке

Имя метода должно быть строкой

Я думаю, это потому, что () и -> не могут быть интерпретированы, так как они являются частью строки? Есть ли какой-нибудь способ добиться этого без необходимости сделайте:

$function1 = getUser;
$function2 = getName;
$object->$function1()->$function2();

Цель состоит в том, чтобы получить массив функций и связать их в цепочку, чтобы вызвать эту цепочку для данного объекта, например:

$functions = array('getCoordinates', 'getLongitude'); // or any other chain call
$functionNames = implode('()->',$functions);
$object->$functionNames()
Author: skirato, 2015-05-19

2 answers

Давайте начнем с более нейтрального текстового формата, с которым легко работать:

$chain = 'getUser.getName';

А затем просто уменьшите это:

$result = array_reduce(explode('.', $chain), function ($obj, $method) {
    return $obj->$method();
}, $object);

Обратите внимание, что вы можете даже проверить $obj, чтобы выяснить, является ли $method методом или свойством или даже индексом массива и return соответствующим значением. Смотрите Веточку для вдохновения.

 13
Author: deceze, 2015-05-19 08:28:01

Я пытаюсь создать универсальный способ фильтрации объектов в массиве и массиве. Иногда эта фильтрация требует вызова цепочки для сравнения определенных полей с заданным значением.

Я думаю, что вместо изобретения нового решения вы можете использовать существующее, например Компонент PropertyAccess из Symfony.

 1
Author: Paweł Wacławczyk, 2016-06-11 07:18:41