使用带标签的服务
编辑本页警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 2.1,现已不再维护。
读本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。
使用带标签的服务
标签是可以应用于任何服务的通用字符串(以及一些选项)。就其本身而言,标记实际上不会以任何方式改变服务的功能。但是如果您选择这样做,您可以向容器构建器请求使用特定标记标记的所有服务的列表。这在编译器传递中非常有用,您可以找到这些服务并以某种特定的方式使用或修改它们。
例如,如果你正在使用Swift Mailer,你可能会想象你想要实现一个“传输链”,这是一个实现类的集合\ Swift_Transport
.使用链,你会希望Swift Mailer尝试多种方式传输消息,直到其中一种成功。
首先,定义TransportChain
类:
12 3 4 5 6 7 8 9 10 11 12 13 14
类TransportChain{私人$传输;公共函数__construct(){$这->传输=数组();}公共函数addTransport(\ Swift_Transport$运输){$这->传输[]=$运输;}}
然后,将链定义为服务:
- YAML
- XML
- PHP
1 2 3 4 5 6
参数:acme_mailer.transport_chain.class:TransportChain服务:acme_mailer.transport_chain:类:“% acme_mailer.transport_chain.class %”
1 2 3 4 5 6 7
<参数><参数关键=“acme_mailer.transport_chain.class”>TransportChain参数>参数><服务><服务id=“acme_mailer.transport_chain”类=“% acme_mailer.transport_chain.class %”/>服务>
1 2 3 4 5
使用ob娱乐下载\组件\DependencyInjection\定义;$容器->setParameter (“acme_mailer.transport_chain.class”,“TransportChain”);$容器->setDefinition (“acme_mailer.transport_chain”,新定义(“% acme_mailer.transport_chain.class %”));
使用自定义标记定义服务
现在你可能想要几个\ Swift_Transport
类自动实例化并添加到链中addTransport ()
方法。例如,您可以添加以下传输作为服务:
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8 9 10 11
服务:acme_mailer.transport.smtp:类:\ Swift_SmtpTransport参数:-“% mailer_host %”标签:-{名称:acme_mailer.transport}acme_mailer.transport.sendmail:类:\ Swift_SendmailTransport标签:-{名称:acme_mailer.transport}
1 2 3 4 5 6 7 8
<服务id=“acme_mailer.transport.smtp”类=“\ Swift_SmtpTransport”><论点>% mailer_host %论点><标签的名字=“acme_mailer.transport”/>服务><服务id=“acme_mailer.transport.sendmail”类=“\ Swift_SendmailTransport”><标签的名字=“acme_mailer.transport”/>服务>
1 2 3 4 5 6 7 8 9
使用ob娱乐下载\组件\DependencyInjection\定义;$definitionSmtp=新定义(“\ Swift_SmtpTransport”,数组(“% mailer_host %”));$definitionSmtp->addTag (“acme_mailer.transport”);$容器->setDefinition (“acme_mailer.transport.smtp”,$definitionSmtp);$definitionSendmail=新定义(“\ Swift_SendmailTransport”);$definitionSendmail->addTag (“acme_mailer.transport”);$容器->setDefinition (“acme_mailer.transport.sendmail”,$definitionSendmail);
请注意,每个标记都被命名为acme_mailer.transport
.这是将在编译器传递中使用的自定义标记。编译器传递使这个标记具有“意义”。
创建一个CompilerPass
你的编译器pass现在可以使用自定义标记向容器请求任何服务:
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
使用ob娱乐下载\组件\DependencyInjection\ContainerBuilder;使用ob娱乐下载\组件\DependencyInjection\编译器\CompilerPassInterface;使用ob娱乐下载\组件\DependencyInjection\参考;类TransportCompilerPass实现了CompilerPassInterface{公共函数过程(ContainerBuilder$容器){如果(!$容器->hasDefinition (“acme_mailer.transport_chain”)) {返回;}$定义=$容器->getDefinition (“acme_mailer.transport_chain”);$taggedServices=$容器->findTaggedServiceIds (“acme_mailer.transport”);foreach($taggedServices作为$id= >$属性){$定义->addMethodCall (“addTransport”,数组(新引用($id)));}}}
的过程()
方法检查是否存在acme_mailer.transport_chain
服务,然后查找所有标记的服务acme_mailer.transport
.它增加了acme_mailer.transport_chain
服务调用addTransport ()
对于每个“acme_mailer”。运输" service it has found. The first argument of each of these calls will be the mailer transport service itself.
将Pass注册到容器中
你还需要在容器中注册这个pass,它将在容器编译时运行:
1 2 3 4
使用ob娱乐下载\组件\DependencyInjection\ContainerBuilder;$容器=新ContainerBuilder ();$容器->addCompilerPass (新TransportCompilerPass);
请注意
如果你使用的是完整的堆栈框架,那么编译器传递的注册方式是不同的。看到如何与编译器传递在捆绑欲知详情。
在标签上添加其他属性
有时,您需要关于使用标记标记的每个服务的附加信息。例如,您可能希望为每个TransportChain添加一个别名。
首先,改变TransportChain
类:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
类TransportChain{私人$传输;公共函数__construct(){$这->传输=数组();}公共函数addTransport(\ Swift_Transport$运输,$别名){$这->传输($别名] =$运输;}公共函数getTransport($别名){如果(array_key_exists ($别名,$这->传输)){返回$这->传输($别名];}其他的{返回;}}}
如你所见,当addTransport
被称为,它需要的不仅仅是一个Swift_Transport
对象,同时也是该传输的字符串别名。那么,如何允许每个带标记的传输服务也提供别名呢?
要回答这个问题,请更改服务声明:
- YAML
- XML
1 2 3 4 5 6 7 8 9 10 11
服务:acme_mailer.transport.smtp:类:\ Swift_SmtpTransport参数:-“% mailer_host %”标签:-{名称:acme_mailer.transport,别名:喷火}acme_mailer.transport.sendmail:类:\ Swift_SendmailTransport标签:-{名称:acme_mailer.transport,别名:酒吧}
1 2 3 4 5 6 7 8
<服务id=“acme_mailer.transport.smtp”类=“\ Swift_SmtpTransport”><论点>% mailer_host %论点><标签的名字=“acme_mailer.transport”别名=“foo”/>服务><服务id=“acme_mailer.transport.sendmail”类=“\ Swift_SendmailTransport”><标签的名字=“acme_mailer.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 29
使用ob娱乐下载\组件\DependencyInjection\ContainerBuilder;使用ob娱乐下载\组件\DependencyInjection\编译器\CompilerPassInterface;使用ob娱乐下载\组件\DependencyInjection\参考;类TransportCompilerPass实现了CompilerPassInterface{公共函数过程(ContainerBuilder$容器){如果(!$容器->hasDefinition (“acme_mailer.transport_chain”)) {返回;}$定义=$容器->getDefinition (“acme_mailer.transport_chain”);$taggedServices=$容器->findTaggedServiceIds (“acme_mailer.transport”);foreach($taggedServices作为$id= >$tagAttributes){foreach($tagAttributes作为$属性){$定义->addMethodCall (“addTransport”,数组(新引用($id),$属性[“别名”)));} } } }
最棘手的部分是美元的属性
变量。因为您可以在同一个服务上多次使用相同的标记(例如,理论上您可以用标记同一个服务5次acme_mailer.transport
标签),美元的属性
该服务上每个标记的标记信息的数组。