如何从Symfony2 config.yml读取配置设置?

jos*_*erk 191 configuration symfony

我已经为我的config.yml文件添加了一个设置:

app.config:
    contact_email: somebody@gmail.com
    ...
Run Code Online (Sandbox Code Playgroud)

对于我的生活,我无法弄清楚如何将其读入变量.我在我的一个控制器中尝试过这样的东西:

$recipient =
$this->container->getParameter('contact_email');
Run Code Online (Sandbox Code Playgroud)

但我得到一个错误说:

必须定义参数"contact_email".

我已经清除了我的缓存,我也在Symfony2重新加载的站点文档中查看了所有内容,但我无法找到如何执行此操作.

可能现在太累了,无法弄明白这一点.有人能帮忙吗?

小智 194

而不是contact_email在其中app.config定义,在parameters条目中定义它:

parameters:
    contact_email: somebody@gmail.com
Run Code Online (Sandbox Code Playgroud)

您应该会发现您在控制器中进行的呼叫现在正常.

  • 如何使用Dev/Prod环境?因此,对于测试,我希望将电子邮件发送到测试电子邮件,生产将收到另一封电子邮件 (4认同)
  • 当我使用这个语句时,我应该在任何地方(控制器,实体,类)注入容器类**$ this-> container-> getParameter('contact_email');**?或者有没有注入容器类更简单的方法? (4认同)
  • @Phill:如果你在symfony2中使用标准的swiftmailer,你可以在config_dev.yml中使用以下设置:`swiftmailer:delivery_address:dev @ example.com`你可以在[Symfony2 cookbook]中找到更多信息(http ://symfony.com/doc/current/cookbook/email/dev_environment.html) (2认同)

Xav*_*ero 171

虽然移动contact_emailto 的解决方案parameters.yml很容易,如其他答案中所提出的,如果您处理许多bundle或者处理嵌套的配置块,那么很容易使参数文件混乱.

  • 首先,我将严格回答这个问题.
  • 稍后,我将给出一种从服务中获取这些配置的方法,而不必通过公共空间作为参数.

第一种方法:分离配置块,将其作为参数

通过扩展(更多关于此处的扩展),您可以将其轻松地"分离"到其中的不同块中config.yml,然后将其作为参数从控制器中获取.

DependencyInjection目录内的Extension类中写下这个:

class MyNiceProjectExtension extends Extension
{
    public function load( array $configs, ContainerBuilder $container )
    {
        // The next 2 lines are pretty common to all Extension templates.
        $configuration = new Configuration();
        $processedConfig = $this->processConfiguration( $configuration, $configs );

        // This is the KEY TO YOUR ANSWER
        $container->setParameter( 'my_nice_project.contact_email', $processedConfig[ 'contact_email' ] );

        // Other stuff like loading services.yml
    }
Run Code Online (Sandbox Code Playgroud)

然后在你的config.yml,config_dev.yml等你可以设置

my_nice_project:
    contact_email: someone@example.com
Run Code Online (Sandbox Code Playgroud)

为了能够config.yml在你内部处理MyNiceBundleExtension你还需要一个Configuration在同一名称空间中的类:

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root( 'my_nice_project' );

        $rootNode->children()->scalarNode( 'contact_email' )->end();

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

然后,您可以从原始问题中获得控制器中的配置,但保持parameters.yml干净,并将其设置config.yml在分开的部分中:

$recipient = $this->container->getParameter( 'my_nice_project.contact_email' );
Run Code Online (Sandbox Code Playgroud)

第二种方法:分离配置块,将配置注入服务

对于寻找类似东西但是从服务中获取配置的读者来说,甚至有一种更好的方式可以永远地混淆"参数"公共空间,甚至不需要container传递给服务(传递整个容器就是练习避免).

上面的这个技巧仍然"注入"你的配置参数空间.

然而,在加载了服务的定义之后,您可以添加一个方法调用,例如setConfig(),只将该块注入服务.

例如,在Extension类中:

class MyNiceProjectExtension extends Extension
{
    public function load( array $configs, ContainerBuilder $container )
    {
        $configuration = new Configuration();
        $processedConfig = $this->processConfiguration( $configuration, $configs );

        // Do not add a paramater now, just continue reading the services.
        $loader = new YamlFileLoader( $container, new FileLocator( __DIR__ . '/../Resources/config' ) );
        $loader->load( 'services.yml' );

        // Once the services definition are read, get your service and add a method call to setConfig()
        $sillyServiceDefintion = $container->getDefinition( 'my.niceproject.sillymanager' );
        $sillyServiceDefintion->addMethodCall( 'setConfig', array( $processedConfig[ 'contact_email' ] ) );
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在您的照片中services.yml定义您的服务,没有任何绝对的变化:

services:
    my.niceproject.sillymanager:
        class: My\NiceProjectBundle\Model\SillyManager
        arguments: []
Run Code Online (Sandbox Code Playgroud)

然后在你的SillyManager课堂上,只需添加方法:

class SillyManager
{
    private $contact_email;

    public function setConfig( $newConfigContactEmail )
    {
        $this->contact_email = $newConfigContactEmail;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这也适用于数组而不是标量值!想象一下,您配置了一个兔子队列,需要主机,用户和密码:

my_nice_project:
    amqp:
        host: 192.168.33.55
        user: guest
        password: guest
Run Code Online (Sandbox Code Playgroud)

当然你需要更改你的树,但是你可以这样做:

$sillyServiceDefintion->addMethodCall( 'setConfig', array( $processedConfig[ 'amqp' ] ) );
Run Code Online (Sandbox Code Playgroud)

然后在服务中做:

class SillyManager
{
    private $host;
    private $user;
    private $password;

    public function setConfig( $config )
    {
        $this->host = $config[ 'host' ];
        $this->user = $config[ 'user' ];
        $this->password = $config[ 'password' ];
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 这应该是答案! (13认同)
  • 优秀!谢谢你的详细解答. (11认同)

Fel*_*oni 34

我必须添加道格拉斯的答案,你可以访问全局配置,但symfony翻译一些参数,例如:

# config.yml
... 
framework:
    session:
        domain: 'localhost'
...
Run Code Online (Sandbox Code Playgroud)

$this->container->parameters['session.storage.options']['domain'];
Run Code Online (Sandbox Code Playgroud)

您可以使用var_dump搜索指定的键或值.


Nik*_*ski 17

为了能够为您的软件包公开一些配置参数,您应该参考文档来执行此操作.这很容易:)

这是链接:如何公开Bundle的语义配置

  • 我同意这一说法.我已经设定了答案,万一有人现在打开这篇文章.感谢负面评价 - 你做了我的一天. (10认同)

Pau*_*nev 7

就像之前所说的那样 - 您可以使用注入容器访问任何参数并使用其参数属性.

"Symfony - 使用容器服务定义"是一篇很好的文章.