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

问题描述 投票:0回答:1
<service id="my_service">
    <tag name="my_transport" supports="feature1, feature2, feature3" />
</service>

在处理 XML 配置时可以将

supports
属性定义为
array
,而不是执行
preg_split

php xml symfony configuration symfony-2.1
1个回答
5
投票

无法将属性定义为

array

DependencyInjection 加载器不支持这一点。 (例如,如果您尝试这样做,从

yml
加载会抛出异常
A "tags" attribute must be of a scalar-type (...)

XmlFileLoader 加载标签 使用 phpize 将属性值解析为 null、布尔值、数字或字符串。

向服务定义添加标签不会覆盖之前添加的标签的定义,而是向数组添加新条目。

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
的 $attributes 将是

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));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.