在Dependency Injection类里使用参数

3.4 版本
维护中的版本

你已经知道了如何在 Symfony服务容器 内部使用配置参数。有几种特殊情况,例如,你可能想使用 %kernel.debug% 参数以便让自己 bundle 中的服务进入 debug 模式。对于这种情况,有更多的工作要做,以便让系统理解参数的值。默认时,你的 %kernel.debug% 参数将被视为一个简单的字符串。看一下这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
// inside Configuration class
// 在 Configuration类 里
$rootNode
    ->children()
        ->booleanNode('logging')->defaultValue('%kernel.debug%')->end()
        // ...
    ->end()
;
 
// inside the Extension class
// 在 Extension类 里
$config = $this->processConfiguration($configuration, $configs);
var_dump($config['logging']);

现在,检查结果以进一步观察:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
my_bundle:
    logging: true
    # true, as expected
    # ture,如同预期

my_bundle:
    logging: '%kernel.debug%'
    # true/false (depends on 2nd parameter of AppKernel),
    # as expected, because %kernel.debug% inside configuration
    # true 还是 false (取决于AppKerenl的第二个参数),正如预期的那样
    # 因为 %kernel.debug% 在被传入到扩展之前,已经在配置文件内被计算出来

my_bundle: ~
# passes the string "%kernel.debug%".
# Which is always considered as true.
# The Configurator does not know anything about
# "%kernel.debug%" being a parameter.
# 传入的字符串 %kernel.debug% 总是被看作是 true
# Configurator 并不知道关于 "%kernel.debug%" 参数的任何信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:my-bundle="http://example.org/schema/dic/my_bundle">
 
    <my-bundle:config logging="true" />
    <!-- true, as expected -->
 
     <my-bundle:config logging="%kernel.debug%" />
     <!-- true/false (depends on 2nd parameter of AppKernel),
          as expected, because %kernel.debug% inside configuration
          gets evaluated before being passed to the extension -->
 
    <my-bundle:config />
    <!-- passes the string "%kernel.debug%".
         Which is always considered as true.
         The Configurator does not know anything about
         "%kernel.debug%" being a parameter. -->
</container>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$container->loadFromExtension('my_bundle', array(
        'logging' => true,
        // true, as expected
    )
);
 
$container->loadFromExtension('my_bundle', array(
        'logging' => "%kernel.debug%",
        // true/false (depends on 2nd parameter of AppKernel),
        // as expected, because %kernel.debug% inside configuration
        // gets evaluated before being passed to the extension
    )
);
 
$container->loadFromExtension('my_bundle');
// passes the string "%kernel.debug%".
// Which is always considered as true.
// The Configurator does not know anything about
// "%kernel.debug%" being a parameter.

为了支持本例,Configuration 类连同此参数,必须通过下述 extension 进行注入:

1
2
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
30
namespace AppBundle\DependencyInjection;
 
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
 
class Configuration implements ConfigurationInterface
{
    private $debug;
 
    public function  __construct($debug)
    {
        $this->debug = (bool) $debug;
    }
 
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('my_bundle');
 
        $rootNode
            ->children()
                // ...
                ->booleanNode('logging')->defaultValue($this->debug)->end()
                // ...
            ->end()
        ;
 
        return $treeBuilder;
    }
}

同时通过 Extension 类在 Configuration 的构造器中对它进行设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace AppBundle\DependencyInjection;
 
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
 
class AppExtension extends Extension
{
    // ...
 
    public function getConfiguration(array $config, ContainerBuilder $container)
    {
        return new Configuration($container->getParameter('kernel.debug'));
    }
}

设置扩展(Extension)中的默认值

在 TwigBundle 和 AsseticBundle 的 Configurator 类里,有一些 %kernel.debug% 的用法。但这是由于默认的参数值是由 Extension 类所设置的。例如 在AsseticBundle 中,你可以找到:

1
$container->setParameter('assetic.debug', $config['debug']);

作为参数传到此处的 %kernel.debug% 字符串,负责容器的解析工作,接下来容器会计算。两种方法都实现了类似的目标。AsseticBundle 不使用 %kernel.debug%,而是新的 %assetic.debug% 参数。

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)