У меня есть цепной вызов:
$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()
Начнем с более нейтрального текстового формата, который прост в обращении:
$chain = 'getUser.getName';
А потом просто уменьшите его:
$result = array_reduce(explode('.', $chain), function ($obj, $method) { return $obj->$method(); }, $object);
Обратите внимание, что вы даже можете проверить $obj
чтобы выяснить, является ли $method
методом или свойством или даже индексом массива и соответствующим образом return
значение. Смотрите Twig для вдохновения.
Я пытаюсь создать общий способ фильтрации объектов в массиве. Иногда для этой фильтрации требуется цепной вызов для сравнения конкретных полей с заданным значением.
Я думаю, что вместо того, чтобы изобретать новое решение, вы можете использовать существующий, например, компонент PropertyAccess от Symfony.