在XML配置中将Symfony 2标记属性定义为数组?

gre*_*emo 1 xml configuration symfony symfony-2.1

<service id="my_service">
    <tag name="my_transport" supports="feature1, feature2, feature3" />
</service>
Run Code Online (Sandbox Code Playgroud)

可以在处理XML配置时定义supports属性array,而不是做一个preg_split

小智 5

没有办法将属性定义为array.

DependencyInjection加载器不支持此功能.(例如,如果您尝试这样,从yml抛出异常加载A "tags" attribute must be of a scalar-type (...))

XmlFileLoader加载标记使用phpize parse属性值为null,boolean,numeric或string.

将标记添加到服务定义不会覆盖先前添加的标记的定义,但会向数组添加新条目.

public function addTag($name, array $attributes = array())
{
    $this->tags[$name][] = $attributes;

    return $this;
}
Run Code Online (Sandbox Code Playgroud)

所以你应该尝试创建多个<tag>元素(如Wouter J所说)

如果您的XML文件是这样的

<service id="my_service">
    <tag name="my_transport" supports="feature1" />
    <tag name="my_transport" supports="feature2" />
    <tag name="my_transport" supports="feature3" />
</service>
Run Code Online (Sandbox Code Playgroud)

然后标签的$属性my_transport将是

Array
(
    [0] => Array
        (
            [supports] => feature1
        )

    [1] => Array
        (
            [supports] => feature2
        )

    [2] => Array
        (
            [supports] => feature3
        )

)
Run Code Online (Sandbox Code Playgroud)

和样本用法

use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;

class MyCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('my_transport_service');

        // Extensions must always be registered before everything else.
        // For instance, global variable definitions must be registered
        // afterward. If not, the globals from the extensions will never
        // be registered.
        $calls = $definition->getMethodCalls();
        $definition->setMethodCalls(array());
        foreach ($container->findTaggedServiceIds('my_transport') as $id => $attributes) {
            // print_r($attributes);
            foreach($attributes as $attrs)
            {
                switch($attrs['supports']){
                  case 'feature1':
                      $definition->addMethodCall('addTransportFeature1', array(new Reference($id)));
                      break;
                  case 'feature2':
                      $definition->addMethodCall('addTransportFeature2', array(new Reference($id)));
                      break;
                  case 'feature3':
                      $definition->addMethodCall('addTransportFeature3', array(new Reference($id)));
                      break;
                }
            }
        }
        $definition->setMethodCalls(array_merge($definition->getMethodCalls(), $calls));
    }
}
Run Code Online (Sandbox Code Playgroud)