如何使用服务标签

编辑本页

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

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

如何使用服务标签

服务标签是一种告诉Symfony或其他第三方欧宝娱乐app下载地址捆绑包您的服务应该以某种特殊方式注册的方式。举个例子:

  • YAML
  • XML
  • PHP
1 2 3 4 5
# app / config / services.yml服务:AppBundle \树枝\ AppExtension:公众:标签:(“twig.extension”)

标记为twig.extension标签在TwigBundle初始化时被收集,并作为扩展添加到Twig。

其他标记用于将服务集成到其他系统中。有关核心Symfony框架中可用的所有标记的列表,请查看欧宝娱乐app下载地址内置的Symfon欧宝娱乐app下载地址y服务标签.每个标签对您的服务有不同的影响,许多标签需要额外的参数(除了的名字参数)。

对于大多数用户,这就是您需要知道的全部内容.如果您想进一步了解如何创建自己的自定义标记,请继续阅读。

可以使用autoconfigure标签

从Symfony 3.3欧宝娱乐app下载地址开始,如果启用的话可以使用autoconfigure,则会自动为您应用一些标签。这对twig.extension标记:容器看到你的类扩展了AbstractExtension(或者更准确地说,它实现了什么ExtensionInterface),并为您添加标签。

如果希望为自己的服务自动应用标记,请使用_instanceof选择:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7 8
# app / config / services.yml服务:# this config只适用于由这个文件创建的服务_instanceof:#类是CustomInterface实例的服务将被自动标记AppBundle \安全\ CustomInterface:标签:(“app.custom_tag”)#……

方法定义自动标记,以满足更高级的需求registerForAutoconfiguration ()方法中的扩展或者来自你的内核:

12 3 4 5 6 7 8 9 10 11 12
/ / app / AppKernel.phpAppKernel扩展内核/ /……受保护的函数构建(ContainerBuilder容器容器->registerForAutoconfiguration (CustomInterface::类)->addTag (“app.custom_tag”);}}

创建自定义标记

标签本身实际上不会以任何方式改变服务的功能。但是如果您选择这样做,您可以向容器构建器请求使用特定标记标记的所有服务的列表。这在编译器传递中非常有用,您可以找到这些服务并以某种特定的方式使用或修改它们。

例如,如果你正在使用Swift Mailer,你可能会想象你想要实现一个“传输链”,这是一个实现类的集合\ Swift_Transport.使用链,你会希望Swift Mailer尝试多种方式传输消息,直到其中一种成功。

首先,定义TransportChain类:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/ / src / AppBundle /邮件/ TransportChain.php名称空间AppBundle邮件TransportChain私人传输公共函数__construct()->运输= [];}公共函数addTransport(\ Swift_Transport运输->传输[]=运输;}}

然后,将链定义为服务:

  • YAML
  • XML
  • PHP
1 2
服务:AppBundle \ \ TransportChain邮件:

使用自定义标记定义服务

现在你可能想要几个\ Swift_Transport类自动实例化并添加到链中addTransport ()方法。例如,您可以将以下传输添加为服务:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7
服务:Swift_SmtpTransport:参数:[' % mailer_host % ')标签:(“app.mail_transport”)Swift_SendmailTransport:标签:(“app.mail_transport”)

注意,每个服务都有一个名为app.mail_transport.这是将在编译器传递中使用的自定义标记。编译器传递使这个标记具有“意义”。

创建编译器通道

你现在可以使用编译器通过方法向容器请求任何服务app.mail_transport标签:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/ / src / AppBundle DependencyInjection /编译器/ MailTransportPass.php名称空间AppBundleDependencyInjection编译器使用AppBundle邮件TransportChain使用欧宝娱乐app下载地址组件DependencyInjection编译器CompilerPassInterface使用欧宝娱乐app下载地址组件DependencyInjectionContainerBuilder使用欧宝娱乐app下载地址组件DependencyInjection参考MailTransportPass实现了CompilerPassInterface公共函数过程(ContainerBuilder容器//总是首先检查是否定义了主服务如果(!容器->(TransportChain::类)){返回;}定义容器->findDefinition (TransportChain::类);//找到所有带有app.mail_transport标签的服务idtaggedServices容器->findTaggedServiceIds (“app.mail_transport”);foreachtaggedServices作为id= >标签) {//将传输服务添加到TransportChain服务定义->addMethodCall (“addTransport”, (引用(id)));}}}

将Pass注册到容器中

类中的容器中,为了在编译容器时运行编译器通道,必须将编译器通道添加到容器中build ()捆绑包的方法:

12 3 4 5 6 7 8 9 10 11 12 13
/ / src / AppBundle / AppBundle.php/ /……使用AppBundleDependencyInjection编译器MailTransportPass使用欧宝娱乐app下载地址组件DependencyInjectionContainerBuilderAppBundle扩展公共函数构建(ContainerBuilder容器容器->addCompilerPass (MailTransportPass ());}}

提示

在实现CompilerPassInterface在服务扩展中,您不需要注册它。看到组件的文档欧宝体育电话获取更多信息。

在标签上添加额外属性

有时,您需要关于使用标记标记的每个服务的附加信息。例如,您可能希望向传输链的每个成员添加别名。

首先,改变TransportChain类:

12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21
TransportChain私人传输公共函数__construct()->运输= [];}公共函数addTransport(\ Swift_Transport运输别名->传输(别名] =运输;}公共函数getTransport别名如果(array_key_exists (别名->传输)){返回->传输(别名];}}}

如你所见,当addTransport ()被称为,它需要的不仅仅是一个Swift_Transport对象,同时也是该传输的字符串别名。那么,如何允许每个带标记的传输服务也提供别名呢?

要回答这个问题,请更改服务声明:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7 8 9
服务:Swift_SmtpTransport:参数:[' % mailer_host % ')标签:-名称:“app.mail_transport”别名:“smtp”Swift_SendmailTransport:标签:-名称:“app.mail_transport”别名:“发送邮件”

提示

在YAML格式中,只要不需要指定额外的属性,就可以将标记作为简单的字符串提供。以下定义是等价的。

12 3 4 5 6 7 8 9 10 11 12
服务:语法紧凑Swift_SendmailTransport:类:\ Swift_SendmailTransport标签:(“app.mail_transport”)#详细语法Swift_SendmailTransport:类:\ Swift_SendmailTransport标签:-名称:“app.mail_transport”

3.3

Symfony 3.3中引入了对YAML格式的紧凑标记符号的支持。欧宝娱乐app下载地址

注意,您添加了一个泛型别名标签的键。要真正使用它,更新编译器:

12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
使用欧宝娱乐app下载地址组件DependencyInjection编译器CompilerPassInterface使用欧宝娱乐app下载地址组件DependencyInjectionContainerBuilder使用欧宝娱乐app下载地址组件DependencyInjection参考TransportCompilerPass实现了CompilerPassInterface公共函数过程(ContainerBuilder容器/ /……foreachtaggedServices作为id= >标签) {//一个服务可以有相同的标记两次foreach标签作为属性) {定义->addMethodCall (“addTransport”, (引用(id),属性“别名”]]);} } } }

双循环可能会让人困惑。这是因为服务可以有多个标记。标记服务两次或两次以上app.mail_transport标签。第二个foreach循环迭代app.mail_transport为当前服务设置的标记,并为您提供属性。

参考标签服务

3.4

在Symfony 3.4中引入了对YAML、XML和PHP中的标记服务符号的支持。欧宝娱乐app下载地址

欧宝娱乐app下载地址Symfony提供了一种快捷方式来注入带有特定标记的所有服务,这在某些应用程序中是一种常见需求,因此您不必为此编写编译器通道。

在下面的例子中,标记为app.handler作为构造函数的第一个参数传递给App \ HandlerCollection服务:

  • YAML
  • XML
  • PHP
12 3 4 5 6 7 8 9 10 11 12
# app / config / services.yml服务:AppBundle \ \处理程序:标签:(“app.handler”)AppBundle \处理器\二:标签:(“app.handler”)AppBundle \ HandlerCollection:#注入所有带有app.handler作为第一个参数的服务参数:-标记的!app.handler

编译完成后HandlerCollectionService能够遍历你的应用程序处理程序:

1 2 3 4 5 6 7 8 9
/ / src / AppBundle / HandlerCollection.php名称空间AppBundleHandlerCollection公共函数__construct(iterable处理程序{}}

提示

方法对收集的服务进行优先级排序优先级属性:

  • YAML
  • XML
  • PHP
1 2 3 4 5
# app / config / services.yml服务:AppBundle \ \处理程序:标签:-名称:“app.handler”优先级:20.

注意,此特性将忽略任何其他自定义属性。

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