在依赖注入类内部使用参数...修复中

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
20
21
my_bundle:
    logging: true
    # true, as expected
    # ture,正如预期

my_bundle:
    logging: '%kernel.debug%'
    # true/false (depends on 2nd parameter of AppKernel),
    # true/false (取决于AppKerenl的第二个参数),
    # as expected, because %kernel.debug% inside configuration
    # gets evaluated before being passed to the extension
    # 正如预期,因为在被传入到扩展之前,%kernel.debug%在configuration内部已经被评估

my_bundle: ~
# passes the string "%kernel.debug%".
# 传入字符串%kernel.debug%。
# Which is always considered as true.
# 总是被看作是true。
# The Configurator does not know anything about
# "%kernel.debug%" being a parameter.
# 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.

为了支持这个用例(译注:让my_bundle: ~模式下不解析成字符串),Configuration 类必须通过以下的扩展来注入这个参数:

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 里,有一些%kernel.debug%的用法,被使用在Configurator类内。然而,这是因为这个默认参数值是由 扩展(Extension) 类设置的。例如在AsseticBundle中,你可以找到:

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

作为一个参数而传到此处的%kernel.debug%字符串,处理的是到这个容器的解析工作,接下来容器要负责评估。TwigBundle 和 AsseticBundle 里的两种方法都实现了类似的目标。AsseticBundle 不使用%kernel.debug%,而是新的%assetic.debug%参数。

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

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