服务容器

编辑本页

警告:您正在浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 3.2,现已不再维护。

本页的更新版本用于Sy欧宝娱乐app下载地址mfony 6.2(当前稳定版本)。

服务容器

您的申请是完整的有用的对象:一个“Mailer”对象可能帮助您发送电子邮件消息,而另一个对象可能帮助您将东西保存到数据库。几乎一切你的应用“做”实际上是由这些对象之一完成的。每次你安装一个新的包,你就可以访问更多!

在Sy欧宝娱乐app下载地址mfony中,调用这些有用的对象服务每个服务都存在于一个非常特殊的对象中服务容器.如果你有服务容器,那么你可以通过服务的id来获取服务:

1 2
日志记录器容器->get (“日志”);entityManager容器->get (“doctrine.orm.entity_manager”);

容器是Sym欧宝娱乐app下载地址fony:它允许您标准化和集中构造对象的方式。它使您的工作更轻松,速度超快,并且强调了促进可重用和解耦代码的体系结构。这也是Symfony如此快速和可扩展的一个重要原因!欧宝娱乐app下载地址

最后,配置和使用服务容器非常简单。在本文结束时,您将能够轻松地通过容器创建自己的对象,并从任何第三方捆绑包定制对象。您将开始编写更具可重用性、可测试性和去耦性的代码,这仅仅是因为服务容器使编写好代码变得如此容易。

获取和使用服务

当您启动Symfony应用程序时,容器欧宝娱乐app下载地址已经包含许多服务。这些就像工具,等着你去利用它们。在你的控制器中,你可以通过$ this - >容器.想要日志什么东西吗?没有问题:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/ / src / AppBundle /控制器/ ProductController.php名称空间AppBundle控制器使用欧宝娱乐app下载地址FrameworkBundle控制器控制器ProductController扩展控制器/ * * *@Route(“产品”)* /公共函数listAction()日志记录器->容器->get (“日志”);日志记录器->信息(“看!我只是使用了一项服务。”);/ /……}}

日志记录器的惟一键吗日志记录器对象。还有其他服务吗?通过运行来找到答案:

1
PHP bin/控制台调试:容器

这只是一个输出示例:

服务ID 类名
学说 学说\包\ DoctrineBundle \注册表
文件系统 欧宝娱乐app下载地址Symfony \文件系统组件\ \文件系统
form.factory 欧宝娱乐app下载地址Symfony \组件\ \ FormFactory形式
日志记录器 欧宝娱乐app下载地址Symfony \ \独白\记录器的桥梁
request_stack 欧宝娱乐app下载地址Symfony \ \ HttpFoundation \ RequestStack组件
路由器 欧宝娱乐app下载地址\包\ FrameworkBundle\路由\路由器
security.authorization_checker 欧宝娱乐app下载地址\组件\安全\核心\授权\ AuthorizationChecker
security.password_encoder 欧宝娱乐app下载地址\组件\安全\核心\编码器\ UserPasswordEncoder
会话 欧宝娱乐app下载地址\组件\ HttpFoundation\会话\会话
翻译 欧宝娱乐app下载地址Symfony \ \翻译\ DataCollectorTranslator组件
嫩枝 Twig_Environment
验证器 欧宝娱乐app下载地址\组件\验证器\验证器\ ValidatorInterface

在整个文档中,您将看到如何使用容器中的许多不同服务。

如果容器保存了这么多有用的对象(服务),这是否意味着这些对象被实例化在每一个请求吗?不!容器是惰性的:它不会实例化服务,直到(并且除非)您请求它。例如,如果你从不使用验证器服务在请求期间,容器永远不会实例化它。

在容器中创建/配置服务

您还可以利用容器来组织您的自己的编码到服务中。例如,假设您希望在用户每次做某事时向他们显示一条随机的、愉快的消息。如果你把这个代码放在控制器中,它就不能被重用。相反,你决定创建一个新类:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/ / src / AppBundle /服务/ MessageGenerator.php名称空间AppBundle服务MessageGenerator公共函数getHappyMessage()消息= (“你做到了!”您更新了系统!神奇的!”“这是我今天看到的最酷的更新之一!”“伟大的工作!继续前进!”,);指数=(用于消息);返回消息指数];}}

恭喜你!您刚刚创建了您的第一个服务类。接下来,你可以服务容器如何要实例化它:

  • YAML
  • XML
  • PHP
1 2 3 4 5
# app / config / services.yml服务:app.message_generator:类:AppBundle \ \ MessageGenerator服务参数:[]

就是这样!您的服务-使用唯一密钥app.message_generator-现在在容器中可用。你可以立即在你的控制器中使用它:

12 3 4 5 6 7 8 9 10 11 12 13 14
公共函数newAction()/ /……//容器将实例化一个新的MessageGenerator()messageGenerator->容器->get (“app.message_generator”);//或使用这个简短的语法// $ message_generator = $this->get('app.message_generator');消息messageGenerator->getHappyMessage ();->addFlash (“成功”消息);/ /……

当你要求app.message_generator服务时,容器构造一个新的MessageGenerator对象并返回它。如果你从不要求app.message_generator请求期间的服务,它是从来没有这也意味着定义大量的服务几乎没有性能开销。

作为奖励,app.message_generator服务只创建一次:每次请求都会返回相同的实例。

向服务中注入服务/配置

如果你想使用日志记录器内部服务MessageGenerator?你的服务有一个$ this - >容器属性:这是一种只有控制器才有的特殊电源。

相反,您应该创建一个__construct ()方法时,添加美元记录器参数,并将其设置为美元记录器属性:

12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20
/ / src / AppBundle /服务/ MessageGenerator.php/ /……使用Psr日志LoggerInterfaceMessageGenerator私人日志记录器公共函数__construct(LoggerInterface日志记录器->记录器=日志记录器;}公共函数getHappyMessage()->日志记录器->信息(“马上就能找到快乐的消息了!”);/ /……}}

提示

LoggerInterface中的输入提示__construct ()方法是可选的,但这是个好主意。可以通过阅读该服务的文档或使用PHP bin/控制台调试:容器控制台命令。

接下来,告诉容器该服务有一个构造函数参数:

  • YAML
  • XML
  • PHP
1 2 3 4 5
# app / config / services.yml服务:app.message_generator:类:AppBundle \ \ MessageGenerator服务参数:(“@logger”)

就是这样!容器现在知道要传递日志记录器类实例化时,将其作为参数MessageGenerator.这被称为依赖注入。

参数Key保存了服务的所有构造函数参数的数组(目前只有1个)。的@符号之前@logger是重要的:它告诉Symfony通过欧宝娱乐app下载地址服务命名日志记录器

但你可以传递任何参数。例如,假设你想让你的类更具可配置性:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/ / src / AppBundle /服务/ MessageGenerator.php/ /……使用Psr日志LoggerInterfaceMessageGenerator私人日志记录器私人loggingEnabled公共函数__construct(LoggerInterface日志记录器loggingEnabled->记录器=日志记录器->loggingEnabled =loggingEnabled;}公共函数getHappyMessage()如果->loggingEnabled) {->日志记录器->信息(“马上就能找到快乐的消息了!”);}/ /……}}

类现在有一个第二个构造函数参数。没问题,只要更新你的服务配置:

  • YAML
  • XML
  • PHP
1 2 3 4 5
# app / config / services.yml服务:app.message_generator:类:AppBundle \ \ MessageGenerator服务参数:[' @logger ',真正的

你甚至可以利用环境在不同的情况下控制这个新值。

服务参数

除了保存服务对象外,容器还保存名为参数.方法下添加参数即可创建参数参数键并使用% parameter_name %语法:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7 8
# app / config / services.yml参数:enable_generator_logging:真正的服务:app.message_generator:类:AppBundle \ \ MessageGenerator服务参数:[' @logger ',“% enable_generator_logging %”

实际上,一旦定义了参数,就可以通过% parameter_name %语法在任何其他类似服务配置文件config.yml.类中定义了许多参数参数。yml文件

你也可以直接从容器中获取参数:

1 2 3 4 5 6 7 8
公共函数newAction()/ /……isLoggingEnabled->容器->getParameter (“enable_generator_logging”);/ /……

请注意

如果您使用以@,您需要通过添加另一个来转义它@

1 2 3 4 5 6 7
# app / config / parameters.yml参数:#这将被解析为字符串'@securepass'mailer_password:“@@securepass”#解析为http://symfony.欧宝娱乐app下载地址com/?foo=%s&bar=%durl_pattern:“http://欧宝娱乐app下载地址www.oldmanjams.com/?foo=%%s&酒吧= % % d '

有关参数的详细信息,请参见参数简介

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