PHP – call_user_function_array или класс Reflection передаются по ссылке?

Я пытаюсь отправить запрос в MVC. У меня есть объект маршрутизации, который соответствует текущему URI для определенных маршрутов. Если есть совпадение, он возвращает экземпляр объекта Route. Через этот объект Route я могу получить доступ к согласованным аргументам контроллера, метода и метода.

Я могу использовать его так:

$route->getClass(); name of controller class to instantiate $route->getMethod(); name of method to call $route->getArgs(); array holding arguments that should be passed to method 

Я также могу добавить новые аргументы, если мне нужно. Например, я могу добавить Contender Injection Contender и текущие экземпляры объекта HTTP-запроса в такие аргументы:

 $route->addArg('container', $container); $route->addArg('request', $request); 

Теперь $ route-> getArgs содержит все аргументы, полученные из URI, но также экземпляр $ container и экземпляр $ request. $ container – контейнер для инъекций зависимости, который я написал. И $ request – объект, представляющий текущий HTTP-запрос.

Поэтому идея состоит в том, чтобы создать экземпляр Router, получить текущий маршрут, а затем добавить объекты, которые я хотел бы использовать внутри каждого контроллера методов / действий. Затем передайте этот объект Route в Dispatcher, и когда будет отправлен запрос, я смогу использовать $ container, $ request и другие аргументы в каждом контроллере методов / действий.

У меня проблема в том, что когда я использую let, скажем, контроллер блога и метод post. По умолчанию и всегда, у него есть экземпляр $ container и $ request (поскольку я ввел их в Route :: $ args, плюс любой другой аргумент / переменную, определенную в определениях маршрутов или полученную из URI.

Поэтому, когда Im в моем блочном контроллере, почтовый метод, я хочу, чтобы он действовал следующим образом:

 public function post($container, $request) { if($request->isAjax) { // -- Its ajax request } $twig = $container->getService("Twig"); } 

Я отправляю запрос примерно так:

Я использую call_user_function_array, чтобы заставить его работать:

 $app = new $controller(); call_user_function_array(array($app, $method), $args); 

Теперь все работает так, как должно, но у меня одна проблема. Когда я использую этот постконтроллер, я должен быть осторожным, в каком порядке упорядочены аргументы post method.

Поэтому я могу это сделать:

 public function post($id, $url, $container, $request) { // -- SNIP -- } 

но я не могу использовать его так:

 public function post($container, $url, $request, $id) { /-- SNIP -- } 

Таким образом, вы получаете проблему, я не могу смешивать аргументы внутри моего метода так, как я хочу, и мне нужно следить за порядком, в котором эти аргументы определяются в Route: $ args array.

Каждый контроллер методов / действий должен иметь $ request и $ container экземпляры плюс аргументы, полученные через URI или определенные в определении маршрута.

Есть ли способ заставить его работать, не думая, в каком порядке метод post получает аргументы? Связано ли это с передачей по ссылке? Поскольку php передает переменные по значению?

Я использую call_user_function_array, и я хочу найти решение для call_user_function_array. Это возможно?

Если нет, это можно сделать, используя класс Reflection?

С классом Reflection вы можете получить имена аргументов каждого параметра функции, которую вы хотите вызвать, и таким образом проверить, находятся ли они в правильном порядке очень легко. Вы не можете сделать это просто с помощью call_user_function_array .

В частности, вы можете использовать метод getParameters() method в классе ReflectionMethod .

Оттуда я думаю, что вы знаете, что делать (проверьте каждый ключ массива параметров с ключом переданного аргумента и там вы пойдете).

Это решение моей проблемы:

Итак, у меня есть все необходимое для отправки запроса:

 $class = "\\Application\\Controller\\Blog"; $method = "post"; $args = array('id' => 1, 'url' => 'some-url', 'container' => DICOBJ, 'request' => RQSTOBJ); 

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

Это то, что нужно сделать:

 $app = new $class(); $rm = new \ReflectionMethod($app, $method); $params = $rm->getParameters(); $argsOrdered = array(); foreach($params as $param) { $argsOrdered[$param->getName()] = $args[$param->getName()]; } call_user_func_array(array($app, $method), $argsOrdered); 

Ta daaa !!!

Итак, что это делает, он получает определенные аргументы пользователем и возвращает их как массив, чтобы пользователь их написал. И тогда мы создаем еще один массив $ argsOrdered, который содержит только аргументы, которые хотят пользователи, заказанные так, как он хочет 🙂

Im использует ReflectionMethod для проверки метода. И в конце call_user_func_array для отправки запроса, но вы также можете использовать класс Reflection для получения экземпляра контроллера.

Это оно. Вы находите это решение элегантным? Можно ли это сделать быстрее?