如何使用服务标签

编辑该页面

警告:你浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 5.2,不再维护。

这个页面的更新版本Symf欧宝娱乐app下载地址ony 6.2(当前的稳定版本)。

如何使用服务标签

服务标签告诉Symfony或者其他第三方包,欧宝娱乐app下载地址您的服务应该注册在某些特殊的方式。下面的例子:

  • YAML
  • XML
  • PHP
1 2 3 4
#配置/ services.yaml服务:App \树枝\ AppExtension:标签:(“twig.extension”)

服务标记twig.extension标签初始化期间收集TwigBundle添加到树枝和扩展。

其他标签用于服务集成到其他系统。可用的所有标记列表的核心Symfony框架,结账欧宝娱乐app下载地址内置Symfony欧宝娱乐app下载地址服务标签。这些对你的服务有不同的影响,许多标签(超出了需要额外的参数的名字参数)。

对于大多数用户来说,这是所有你需要知道的。如果你想更进一步,学习如何创建自己的自定义标签,继续阅读。

可以使用autoconfigure标签

如果你使可以使用autoconfigure,然后有些标签自动申请你。这是真实的twig.extension标签:容器看到您的类扩展AbstractExtension(或更准确地说,它实现了ExtensionInterface)并添加标签。

如果你想标记自动申请自己的服务,使用_instanceof选择:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7 8
#配置/ services.yaml服务:#这配置只适用于由该文件的服务_instanceof:#服务的类的实例CustomInterface将被自动标记App \安全\ CustomInterface:标签:(“app.custom_tag”)#……

对于更高级的需求,您可以定义自动标签使用registerForAutoconfiguration ()方法。

在Symf欧宝娱乐app下载地址ony应用程序中,您的内核类中调用这个方法:

1 2 3 4 5 6 7 8 9 10 11 12
/ / src / Kernel.php内核扩展BaseKernel{/ /……受保护的函数构建(ContainerBuilder美元容器):无效{美元容器- >registerForAutoconfiguration (CustomInterface::类)- >addTag (“app.custom_tag”);}}

在Symf欧宝娱乐app下载地址ony包,调用这个方法load ()的方法束扩展类:

1 2 3 4 5 6 7 8 9 10 11 12
/ / src / DependencyInjection / MyBundleExtension.phpMyBundleExtension扩展扩展{/ /……公共函数负载(数组美元配置,ContainerBuilder美元容器):无效{美元容器- >registerForAutoconfiguration (CustomInterface::类)- >addTag (“app.custom_tag”);}}

创建自定义标签

标记自己实际上并不以任何方式改变您的服务的功能。但是如果你选择,你可以问一个容器建造者的所有服务的列表和一些特定的标签标记。这是有用的在编译器,您可以找到这些服务和在一些特定的方式使用或修改它们。

例如,如果您使用的是斯威夫特梅勒你想象你想实现一个“传递链”,这是一个集合类实现\ Swift_Transport。用链式,你要迅速梅勒尝试多种方式运输到一个成功的消息。

首先,定义TransportChain类:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/ / src /邮件/ TransportChain.php名称空间应用程序\邮件;TransportChain{私人美元传输;公共函数__construct(){美元- >传输= [];}公共函数addTransport(\ Swift_Transport美元运输):无效{美元- >传输[]=美元运输;}}

然后,定义链作为一个服务:

  • YAML
  • XML
  • PHP
1 2 3
#配置/ services.yaml服务:邮件\ App \ TransportChain:~

定义服务的定制标记

现在你可能会想要一些的\ Swift_Transport类实例化并使用自动添加到链addTransport ()方法。例如,您可以添加以下运输服务:

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

注意,每个服务被标签命名app.mail_transport。这是自定义标签,您将使用在你的编译器通过。编译器通过使这个标记“的意思是”什么。

创建一个编译器通过

您现在可以使用编译器通过向容器的任何服务app.mail_transport标签:

1 2 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 / DependencyInjection /编译器/ MailTransportPass.php名称空间应用程序\DependencyInjection\编译器;使用应用程序\邮件\TransportChain;使用欧宝娱乐app下载地址\组件\DependencyInjection\编译器\CompilerPassInterface;使用欧宝娱乐app下载地址\组件\DependencyInjection\ContainerBuilder;使用欧宝娱乐app下载地址\组件\DependencyInjection\参考;MailTransportPass实现了CompilerPassInterface{公共函数过程(ContainerBuilder美元容器):无效{/ /总首先检查如果主服务定义如果(!美元容器- >(TransportChain::类)){返回;}美元定义=美元容器- >findDefinition (TransportChain::类);/ /查找所有服务id app.mail_transport标签美元taggedServices=美元容器- >findTaggedServiceIds (“app.mail_transport”);foreach(美元taggedServices作为美元id= >美元标签){/ /添加TransportChain服务的运输服务美元定义- >addMethodCall (“addTransport”,(引用(美元id)));}}}

注册通过的容器

为了运行编译器编译通过当容器,你必须编译器通过添加到容器中包的扩展或从你的内核:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/ / src / Kernel.php名称空间应用程序;使用应用程序\DependencyInjection\编译器\MailTransportPass;使用欧宝娱乐app下载地址\组件\HttpKernel\内核作为BaseKernel;/ /……内核扩展BaseKernel{/ /……受保护的函数构建(ContainerBuilder美元容器):无效{美元容器- >addCompilerPass (MailTransportPass ());}}

提示

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

添加额外的属性标签

有时你需要额外信息的每个服务标记你的标签。例如,您可能想添加别名来传递链的每个成员。

首先,改变TransportChain类:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日
TransportChain{私人美元传输;公共函数__construct(){美元- >传输= [];}公共函数addTransport(\ Swift_Transport美元运输,美元别名):无效{美元- >传输(美元别名]=美元运输;}公共函数getTransport(美元别名):? \Swift_Transport{如果(array_key_exists (美元别名,美元- >传输)){返回美元- >传输(美元别名];}返回;}}

正如您可以看到的,什么时候addTransport ()被调用时,不仅需要一个吗Swift_Transport对象,也是一个字符串别名运输。所以,你怎么能让每个标记运输服务也提供一个别名吗?

要回答这个问题,改变服务宣言:

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

提示

在YAML格式,您可以提供标签作为一个简单的字符串,只要你不需要指定附加属性。下面的定义是等价的。

1 2 3 4 5 6 7 8 9 10 11 12
#配置/ services.yaml服务:#紧凑语法Swift_SendmailTransport:类:\ Swift_SendmailTransport标签:(“app.mail_transport”)#详细的语法Swift_SendmailTransport:类:\ Swift_SendmailTransport标签:- - - - - -{名称:“app.mail_transport”}

注意到你已经添加了一个通用的别名标签的关键。使用这个,更新编译器:

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

双圈可能会让人困惑。这是因为一个服务可以有多个标签。你标记两次或更多的服务app.mail_transport标签。第二个foreach循环遍历app.mail_transport标签设置为当前服务和给你的属性。

参考标记服务

欧宝娱乐app下载地址Symfony提供了一个快捷方式将所有服务标记与一个特定的标签,这是一种常见的需要在某些应用程序中,所以你不必编写编译器通过。

在以下示例中,所有服务标记app.handler作为第一个构造函数参数传递给吗App \ HandlerCollection服务:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7 8 9 10 11 12
#配置/ services.yaml服务:应用\ \处理程序:标签:(“app.handler”)App \处理器\二:标签:(“app.handler”)App \ HandlerCollection:#注入所有服务标记app.handler作为第一个参数参数:- - - - - -tagged_iterator !app.handler

编译后HandlerCollection服务是能够遍历应用程序处理程序:

1 2 3 4 5 6 7 8 9
/ / src / HandlerCollection.php名称空间应用程序;HandlerCollection{公共函数__construct(iterable美元处理程序){}}

另请参阅

另请参阅标记定位服务

标记服务与优先级

标记服务可以优先使用优先级属性。优先级是一个积极或消极的整数。数越高,越早标记服务将位于集合:

  • YAML
  • XML
  • PHP
1 2 3 4 5
#配置/ services.yaml服务:应用\ \处理程序:标签:- - - - - -{名称:“app.handler”,优先级:20.}

另一个选择,这是特别有用,当使用autoconfigure标签,是实现静态getDefaultPriority ()服务本身上的方法:

1 2 3 4 5 6 7 8 9 10
/ / src /处理/ One.php名称空间应用程序\处理程序;一个{公共静态函数getDefaultPriority():int{返回3;}}

如果你想要另一个方法定义优先级(如。getPriority ()而不是getDefaultPriority ()),您可以定义它的配置收集服务:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6
#配置/ services.yaml服务:App \ HandlerCollection:#注入所有服务标记app.handler作为第一个参数参数:- - - - - -tagged_iterator !{标签:app.handler,default_priority_method:getPriority}

标记服务指数

如果你想在注入集合中检索一个特定的服务可以使用index_bydefault_index_method选项的参数结合tagged_iterator !

使用前面的例子,这个服务配置创建一个索引的集合关键属性:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7 8 9 10 11 12
#配置/ services.yaml服务:应用\ \处理程序:标签:- - - - - -{名称:“app.handler”,关键:“handler_one”}App \处理器\二:标签:- - - - - -{名称:“app.handler”,关键:“handler_two”}App \ HandlerCollection:参数:[! tagged_iterator{标签:“app.handler”,index_by:“关键”})

编译后HandlerCollection可以遍历应用程序处理程序。从迭代器来检索一个特定的服务,调用iterator_to_array ()函数,然后使用关键属性的数组元素。例如,检索handler_two处理程序:

1 2 3 4 5 6 7 8 9 10 11 12
/ / src /处理/ HandlerCollection.php名称空间应用程序\处理程序;HandlerCollection{公共函数__construct(iterable美元处理程序){美元处理程序=美元处理程序运算符\可反驳的?iterator_to_array (美元处理程序):美元处理程序;美元handlerTwo=美元处理程序(“handler_two”];}}

提示

优先级一样,你也可以实现一个静态的getDefaultIndexName ()方法处理程序和省略索引属性(关键):

1 2 3 4 5 6 7 8 9 10 11
/ / src /处理/ One.php名称空间应用程序\处理程序;一个{/ /……公共静态函数getDefaultIndexName():字符串{返回“handler_one”;}}

您还可以定义静态方法的名称来实现在每个服务default_index_method属性标记的论点:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7
#配置/ services.yaml服务:#……App \ HandlerCollection:#使用getIndex()而不是getDefaultIndexName ()参数:[! tagged_iterator{标签:“app.handler”,default_index_method:“getIndex”})
这项工作,包括代码示例,许可下Creative Commons冲锋队3.0许可证。