我最近将Symfony的Routing和HttpFoundation组件插入到我的旧应用程序中,并且我正在慢慢地开始转换我的所有代码。
到目前为止,一切都运行得出奇地好,但我认为我正在朝着一个兔子洞前进,我已经构建了我的控制器和路由器调用它们的方式。以下是位于我的前端控制器中的一些代码:
// look up the controller and action defined in routes.yml
$parameter = $router->match($request->getPathInfo());
// call the action and get the output
$output = call_user_func('MyCompany''Controller''' . $parameter['_controller']);
// send the output in the response and so forth
// ....
因此,call_user_func行实际上会调用类似MyCompany'Controller'GeneralController::indexAction
的东西,它最终返回在响应中发送的html输出。
由于我设置一切的方式,我必须使用像return self::display('filename.tpl');
这样的语句。这在我看来是不对的。是否有更好的方法来调用这些控制器动作?
您可能需要使用ControllerResolver。或者你可能想要更直接地使用HttpKernel,它会为你做解析。
如果你使用ControllerResolver,它会创建一个"callable",也可以获取你可以做的参数$response = call_user_func_array($controller, $arguments);
使用HttpKernel或AppKernel还有很多其他好处,它们提供了更多的脚手架。
你遇到的问题,实际上是依赖注入。self::display
可能会使用一些全局变量(对象)为您呈现一些模板,您需要做的是像$this->renderer->render('filename.tpl')
这样的事情。要做到这一点,无需声明服务容器等并将它们连接到路由器,最简单的方法是为所有控制器提供一些共同参数,即:call_user_func('MyCompany''Controller''' . $parameter['_controller']);
变为call_user_func_array('MyCompany''Controller''' . $parameter['_controller'], ['array', 'of', 'common', 'dependencies']);
或者你可以创建一个服务定位器(symfony术语中的服务容器),并将其传递给所有控制器,让它们获取自己的依赖项。