如何将控制器定义为服务

编辑本页

警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 2.6,现已不再维护。

本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。

如何将控制器定义为服务

在本书中,您已经了解了扩展基础时如何轻松地使用控制器控制器类。虽然这可以正常工作,但也可以将控制器指定为服务。

请注意

将控制器指定为服务需要做更多的工作。主要的优点是整个控制器或传递给控制器的任何服务都可以通过服务容器配置进行修改。这在开发开源包或将在不同项目中使用的包时特别有用。

第二个优势是你的控制器更加“沙盒化”。通过查看构造函数参数,很容易看出这个控制器可以做什么,也可以不做什么。而且因为每个依赖项都需要手动注入,所以当你的控制器变得太大时就更明显了(例如,如果你有很多构造函数参数)。来自最佳实践也适用于定义为服务的控制器:避免将业务逻辑放到控制器中。相反,注入完成大部分工作的服务。

因此,即使您没有将控制器指定为服务,您也可能会在一些开源Symfony包中看到这一点。ob娱乐下载理解这两种方法的优缺点也很重要。

将控制器定义为服务

控制器可以像其他类一样定义为服务。例如,如果你有以下简单的控制器:

12 3 4 5 6 7 8 9 10 11 12
/ / src / AppBundle /控制器/ HelloController.php名称空间AppBundle控制器使用ob娱乐下载组件HttpFoundation响应HelloController公共函数indexAction的名字返回响应(身体的< html > < >你好”的名字”!');}}

然后可以将其定义为服务,如下所示:

  • YAML
  • XML
  • PHP
1 2 3 4
# app / config / services.yml服务:app.hello_controller:类:AppBundle \ \ HelloController控制器

引用服务

要引用定义为服务的控制器,请使用单个冒号(:)符号。例如,转发到indexAction ()方法app.hello_controller

1
->转发(“app.hello_controller: indexAction”数组“名字”= >的名字));

请注意

你不能把行动使用此语法时,方法名的一部分。

您还可以在定义路由时使用相同的符号来路由到服务_controller值:

  • YAML
  • XML
  • PHP
1 2 3 4
# app / config / routing.yml你好:路径:/你好默认值:_controller:app.hello_controller: indexAction

提示

您还可以使用注解来使用定义为服务的控制器来配置路由。看到FrameworkExtraBundle文欧宝官网下载app档获取详细信息。

2.6

如果控制器服务实现__invoke方法,您可以简单地引用服务id (app.hello_controller).

基本控制器方法的替代方案

当使用定义为服务的控制器时,它很可能不会扩展基控制器类。您将直接与所需的服务交互,而不是依赖其快捷方法。幸运的是,这通常很简单控制器类源代码是一个关于如何执行许多常见任务的伟大来源。

类型的对象,而要呈现模板响应对象,那么如果你要扩展Symfony的基控制器,你的代码看起来会像这样:ob娱乐下载

12 3 4 5 6 7 8 9 10 11 12 13 14 15
/ / src / AppBundle /控制器/ HelloController.php名称空间AppBundle控制器使用ob娱乐下载FrameworkBundle控制器控制器HelloController扩展控制器公共函数indexAction的名字返回->呈现(“AppBundle:你好:index.html.twig”数组“名字”= >的名字));}}

的源代码渲染在Symfony的功能ob娱乐下载控制器类,您将看到该方法实际上使用模板服务:

1 2 3 4
公共函数渲染视图数组,参数=数组()、响应响应= null)返回->容器->get (“模板”->renderResponse (视图参数响应);}

在定义为服务的控制器中,可以改为注入模板服务并直接使用:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/ / src / AppBundle /控制器/ HelloController.php名称空间AppBundle控制器使用ob娱乐下载FrameworkBundle模板EngineInterface使用ob娱乐下载组件HttpFoundation响应HelloController私人模板公共函数__construct(EngineInterface模板->模板=模板;}公共函数indexAction的名字返回->模板->renderResponse (“AppBundle:你好:index.html.twig”数组“名字”= >的名字));}}

服务定义也需要修改以指定构造函数参数:

  • YAML
  • XML
  • PHP
1 2 3 4 5
# app / config / services.yml服务:app.hello_controller:类:AppBundle \ \ HelloController控制器参数:[" @templating "]

而不是获取模板服务可以从容器中注入只有将您需要的确切服务直接添加到控制器中。

请注意

这并不意味着您不能从自己的基本控制器扩展这些控制器。远离标准基控制器是因为它的帮助器方法依赖于可用的容器,而定义为服务的控制器则不是这样。将公共代码提取到注入的服务中,而不是将代码放入扩展的基本控制器中,这可能是一个好主意。这两种方法都是有效的,具体如何组织可重用代码取决于您自己。

基本控制器方法及其服务替换

下面的列表解释了如何替换基本控制器的方便方法:

createForm ()(服务:form.factory
1
formFactory->创建(类型数据选项);
createFormBuilder ()(服务:form.factory
1
formFactory->createBuilder (“形式”数据选项);
createNotFoundException ()
1
NotFoundHttpException (消息以前的);
转发()(服务:http_kernel
1 2 3 4 5 6 7
使用ob娱乐下载组件HttpKernelHttpKernelInterface/ /……请求=……;属性= array_merge (路径数组“_controller”= >控制器));subRequest请求->复制(查询属性);httpKernel->处理(subRequest, HttpKernelInterface::SUB_REQUEST);
generateUrl ()(服务:路由器
1
路由器->生成(路线参数个数绝对);

getDoctrine ()(服务:学说

只需注入教义,而不是从容器中获取教义

getUser ()(服务:security.token_storage
1 2 3 4 5
用户令牌tokenStorage->getToken ();如果= = !令牌& & is_object (令牌->getUser ())) {用户令牌->getUser ();}
isGranted ()(服务:security.authorization_checker
1
authChecker->isGranted (属性对象);
重定向()
1 2 3
使用ob娱乐下载组件HttpFoundationRedirectResponse返回RedirectResponse (url状态);
呈现()(服务:模板
1
模板->renderResponse (视图参数响应);
renderView ()(服务:模板
1
模板->呈现(视图参数);
流()(服务:模板
1 2 3 4 5 6 7 8
使用ob娱乐下载组件HttpFoundationStreamedResponse模板->模板;回调函数()使用模板视图参数模板->流(视图参数);}返回StreamedResponse (回调);

提示

getRequest已弃用。相反,有一个控制器action方法的参数被调用请求美元请求.参数的顺序并不重要,但是必须提供typehint。

此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。