如何使用服务标签
编辑本页如何使用服务标签
服务标签是一种告诉Symfony或其他第三方ob娱乐下载捆绑包您的服务应该以某种特殊方式注册的方式。举个例子:
- YAML
- XML
- PHP
1 2 3 4
#配置/ services.yaml服务:App \树枝\ AppExtension:标签:(“twig.extension”)
标记为twig.extension
标签在TwigBundle初始化时被收集,并作为扩展添加到Twig。
其他标记用于将服务集成到其他系统中。有关核心Symfony框架中可用的所有标记的列表,请查看ob娱乐下载内置的Symfonob娱乐下载y服务标签.每个标签对您的服务有不同的影响,许多标签需要额外的参数(除了的名字
参数)。
对于大多数用户,这就是您需要知道的全部内容.如果您想进一步了解如何创建自己的自定义标记,请继续阅读。
可以使用autoconfigure标签
如果你启用可以使用autoconfigure,则会自动为您应用一些标签。这对twig.extension
标记:容器看到你的类扩展了AbstractExtension
(或者更准确地说,它实现了什么ExtensionInterface
),并为您添加标签。
如果希望为自己的服务自动应用标记,请使用_instanceof
选择:
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8
#配置/ services.yaml服务:# this config只适用于由这个文件创建的服务_instanceof:#类是CustomInterface实例的服务将被自动标记App \安全\ CustomInterface:标签:(“app.custom_tag”)#……
方法定义自动标记,以满足更高级的需求registerForAutoconfiguration ()方法。
在Symfob娱乐下载ony应用程序中,在内核类中调用这个方法:
12 3 4 5 6 7 8 9 10 11 12
/ / src / Kernel.php类内核扩展BaseKernel{/ /……受保护的函数构建(ContainerBuilder$容器):无效{$容器->registerForAutoconfiguration (CustomInterface::类)->addTag (“app.custom_tag”);}}
在Symfob娱乐下载ony包中,在load ()
方法Bundle扩展类:
12 3 4 5 6 7 8 9 10 11 12
/ / src / DependencyInjection / MyBundleExtension.php类MyBundleExtension扩展扩展{/ /……公共函数负载(数组$配置, ContainerBuilder$容器):无效{$容器->registerForAutoconfiguration (CustomInterface::类)->addTag (“app.custom_tag”);}}
创建自定义标记
标签本身实际上不会以任何方式改变服务的功能。但是如果您选择这样做,您可以向容器构建器请求使用特定标记标记的所有服务的列表。这在编译器传递中非常有用,您可以找到这些服务并以某种特定的方式使用或修改它们。
例如,如果您正在使用Symfony Mailer组件,您可能希望实现ob娱乐下载一个“传输链”,它是实现的类的集合\ MailerTransport
.使用链,您将希望Mailer尝试多种方式传输消息,直到其中一种成功。
首先,定义TransportChain
类:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/ / src /邮件/ TransportChain.php名称空间应用程序\邮件;类TransportChain{私人$传输;公共函数__construct(){$这->运输= [];}公共函数addTransport(\ MailerTransport$运输):无效{$这->传输[]=$运输;}}
然后,将链定义为服务:
- YAML
- XML
- PHP
1 2 3
#配置/ services.yaml服务:邮件\ App \ TransportChain:~
使用自定义标记定义服务
现在你可能想要几个\ MailerTransport
类自动实例化并添加到链中addTransport ()
方法。例如,您可以将以下传输添加为服务:
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8
#配置/ services.yaml服务:MailerSmtpTransport:参数:[' % mailer_host % ')标签:(“app.mail_transport”)MailerSendmailTransport:标签:(“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 / DependencyInjection /编译器/ MailTransportPass.php名称空间应用程序\DependencyInjection\编译器;使用应用程序\邮件\TransportChain;使用ob娱乐下载\组件\DependencyInjection\编译器\CompilerPassInterface;使用ob娱乐下载\组件\DependencyInjection\ContainerBuilder;使用ob娱乐下载\组件\DependencyInjection\参考;类MailTransportPass实现了CompilerPassInterface{公共函数过程(ContainerBuilder$容器):无效{//总是首先检查是否定义了主服务如果(!$容器->(TransportChain::类)){返回;}$定义=$容器->findDefinition (TransportChain::类);//找到所有带有app.mail_transport标签的服务id$taggedServices=$容器->findTaggedServiceIds (“app.mail_transport”);foreach($taggedServices作为$id= >$标签){//将传输服务添加到TransportChain服务$定义->addMethodCall (“addTransport”, (新引用($id)));}}}
将Pass注册到容器中
类的容器中,为了在编译容器时运行编译器通道,必须将编译器通道添加到容器中包的扩展或者来自你的内核:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/ / src / Kernel.php名称空间应用程序;使用应用程序\DependencyInjection\编译器\MailTransportPass;使用ob娱乐下载\组件\HttpKernel\内核作为BaseKernel;/ /……类内核扩展BaseKernel{/ /……受保护的函数构建(ContainerBuilder$容器):无效{$容器->addCompilerPass (新MailTransportPass ());}}
提示
在实现CompilerPassInterface
在服务扩展中,您不需要注册它。看到组件的文档欧宝官网下载app获取更多信息。
在标签上添加额外属性
有时,您需要关于使用标记标记的每个服务的附加信息。例如,您可能希望向传输链的每个成员添加别名。
首先,改变TransportChain
类:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
类TransportChain{私人$传输;公共函数__construct(){$这->运输= [];}公共函数addTransport(\ MailerTransport$运输,$别名):无效{$这->传输($别名] =$运输;}公共函数getTransport($别名): ? \MailerTransport{如果(array_key_exists ($别名,$这->传输)){返回$这->传输($别名];}返回零;}}
如你所见,当addTransport ()
被称为,它需要的不仅仅是一个MailerTransport
对象,同时也是该传输的字符串别名。那么,如何允许每个带标记的传输服务也提供别名呢?
要回答这个问题,请更改服务声明:
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8 9 10
#配置/ services.yaml服务:MailerSmtpTransport:参数:[' % mailer_host % ')标签:-{名称:“app.mail_transport”,别名:“smtp”}MailerSendmailTransport:标签:-{名称:“app.mail_transport”,别名:“发送邮件”}
提示
在YAML格式中,只要不需要指定额外的属性,就可以将标记作为简单的字符串提供。以下定义是等价的。
12 3 4 5 6 7 8 9 10 11 12
#配置/ services.yaml服务:语法紧凑MailerSendmailTransport:类:\ MailerSendmailTransport标签:(“app.mail_transport”)#详细语法MailerSendmailTransport:类:\ MailerSendmailTransport标签:-{名称:“app.mail_transport”}
注意,您添加了一个泛型别名
标签的键。要真正使用它,更新编译器:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
使用ob娱乐下载\组件\DependencyInjection\编译器\CompilerPassInterface;使用ob娱乐下载\组件\DependencyInjection\ContainerBuilder;使用ob娱乐下载\组件\DependencyInjection\参考;类TransportCompilerPass实现了CompilerPassInterface{公共函数过程(ContainerBuilder$容器):无效{/ /……foreach($taggedServices作为$id= >$标签){//一个服务可以有相同的标记两次foreach($标签作为$属性){$定义->addMethodCall (“addTransport”, (新引用($id),$属性[“别名”)));} } } }
双循环可能会让人困惑。这是因为服务可以有多个标记。标记服务两次或两次以上app.mail_transport
标签。第二个foreach
循环迭代app.mail_transport
为当前服务设置的标记,并为您提供属性。
参考标签服务
ob娱乐下载Symfony提供了一种快捷方式来注入带有特定标记的所有服务,这在某些应用程序中是一种常见需求,因此您不必为此编写编译器通道。
在下面的例子中,标记为app.handler
作为构造函数的第一个参数传递给App \ HandlerCollection
服务:
- YAML
- XML
- PHP
12 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
Service能够遍历你的应用程序处理程序:
1 2 3 4 5 6 7 8 9
/ / src / HandlerCollection.php名称空间应用程序;类HandlerCollection{公共函数__construct(iterable$处理程序){}}
另请参阅
另请参阅标记定位器服务
带优先级标签的服务
标记的服务可以使用优先级
属性。优先级是一个默认为的正整数或负整数0
.数字越高,被标记的服务在集合中的位置就越早:
- YAML
- XML
- PHP
1 2 3 4 5
#配置/ services.yaml服务:应用\ \处理程序:标签:-{名称:“app.handler”,优先级:20.}
另一个选项(在使用自动配置标记时特别有用)是实现静态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_by
而且default_index_method
参数组合的选项tagged_iterator !
.
使用前面的示例,此服务配置创建一个由关键
属性:
- YAML
- XML
- PHP
12 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
处理程序:
12 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”})