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

时间:2012-11-25 18:15:15

标签: xml symfony configuration symfony-2.1

<service id="my_service">
    <tag name="my_transport" supports="feature1, feature2, feature3" />
</service>

在处理XML配置时,可以将supports属性定义为array,而不是preg_split吗?

1 个答案:

答案 0 :(得分:5)

无法将属性定义为array

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

XmlFileLoader loading tags使用phpize parse属性值为null,boolean,numeric或string。

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

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

    return $this;
}

所以你应该尝试创建多个<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>

然后标记my_transport的$属性将为

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

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

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

)

样本用法

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));
    }
}