PHP - call_user_function_array 或 Reflection 类通过引用传递?

标签 php oop model-view-controller dispatcher router

我正在尝试在 MVC 框架中分派(dispatch)请求。 我有一个路由对象,它将当前 URI 与定义的路由进行匹配。如果存在匹配,则返回 Route 对象的实例。通过该 Route 对象,我可以访问匹配的 Controller 、方法和方法参数。

我可以这样使用它:

$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

如果需要,我还可以添加新参数。例如,我可以将依赖注入(inject)容器和当前 HTTP 请求对象实例添加到 args,如下所示:

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

现在 $route->getArgs 保存从 URI 获取的所有参数,还有 $container 实例和 $request 实例。 $container 是我写的依赖注入(inject)容器。 $request是代表当前HTTP请求的对象。

所以我们的想法是实例化 Router,获取当前 Route,然后添加我想在每个方法/ Action Controller 中使用的对象。然后将该 Route 对象传递给 Dispatcher,当调度请求时,我将能够在每个方法/操作 Controller 中使用 $container、$request 和其他参数。

我遇到的问题是,当我使用博客 Controller 和发布方法时。默认情况下,并且始终,它应该具有 $container 和 $request 的实例(因为我将它们插入 Route::$args,以及路由定义中定义或从 URI 获取的任何其他参数/​​变量。

所以当我在我的博客 Controller 中时,发布方法我希望它的行为如下:

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);

现在一切都正常了,但我有一个问题。 当我使用该后置 Controller 时,我必须小心后置方法参数的排序顺序。

所以我可以这样做:

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

但我不能这样使用它:

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

所以你遇到了问题,我无法按照我想要的方式在方法中混合参数,并且我需要密切关注这些参数在 Route:$args 数组中定义的顺序。

每个方法/操作 Controller 都应该有 $request 和 $container 实例以及通过 URI 获取或在路由定义中定义的参数。

有没有办法让它工作而不必考虑post方法获取参数的顺序?这与引用传递有关系吗?既然php按值传递变量?

我正在使用 call_user_function_array,我想找到 call_user_function_array 的解决方案。 这可能吗?

如果没有,可以使用 Reflection 类来完成吗?

最佳答案

这是我的问题的解决方案:

所以,我拥有发送请求所需的一切:

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

现在我需要分派(dispatch)该请求,以便用户可以根据需要以任何顺序插入参数。

这是应该做的:

$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);

哒哒!!!

因此,它的作用是获取用户定义的参数,并按照用户编写它们的顺序将它们作为数组返回。然后我们创建另一个 $argsOrdered 数组,它只保存用户想要的参数,按照他想要的方式排序:)

我使用 ReflectionMethod 来检查方法。最后调用_user_func_array来调度请求,但您也可以使用Reflection类来获取 Controller 实例。

就是这样。您觉得这个解决方案优雅吗?这可以更快地完成吗?

关于PHP - call_user_function_array 或 Reflection 类通过引用传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12976855/

相关文章:

php - 有没有一种简单的方法可以从 PHP 中的国家/地区代码获取语言代码

php - MySQL 查询随机滞后

javascript - 面向对象的 JavaScript : Call method from inside of Callback Function

java - 如何在我的 ArrayList 中搜索特定人员的详细信息?我将如何编辑或删除它们?

javascript - Node.JS-Express : Coding style

php - 为每个实际用户创建用户?

JavaScript 类型问题 : Uncaught TypeError: Object 0 has no method 'draw'

javascript - AngularJS - 最佳实践 : model properties on view or function calls?

javascript - 仅使用 Backbone.js 更新某些模型属性

php - 使用 sha1 和 salt 存储密码