195

我在我的 config.yml 文件中添加了一个设置,如下所示:

app.config:
    contact_email: somebody@gmail.com
    ...

对于我的生活,我无法弄清楚如何将它读入变量。我在我的一个控制器中尝试了这样的事情:

$recipient =
$this->container->getParameter('contact_email');

但我收到一条错误消息:

必须定义参数“contact_email”。

我已经清除了我的缓存,我还在 Symfony2 重新加载的站点文档上到处查看,但我不知道如何做到这一点。

可能只是太累了,现在想不通。有人能帮忙吗?

4

6 回答 6

195

contact_email与其定义within ,不如app.config在一个parameters条目中定义它:

parameters:
    contact_email: somebody@gmail.com

您应该会发现您在控制器中进行的调用现在可以正常工作了。

于 2011-01-30T20:45:33.713 回答
174

虽然移动contact_email到的解决方案parameters.yml很容易,正如其他答案中所建议的那样,但如果您处理许多捆绑包或处理嵌套的配置块,这很容易使您的参数文件变得混乱。

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

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

使用扩展(更多关于扩展在这里),您可以轻松地将其“分离”到不同的块中config.yml,然后将其作为可从控制器获取的参数注入。

在目录内的 Extension 类中DependencyInjection写入以下内容:

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
    }

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

my_nice_project:
    contact_email: someone@example.com

为了能够在您的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;
    }
}

然后,您可以根据原始问题中的需要从控制器获取配置,但要保持parameters.yml清洁,并将其设置config.yml在单独的部分中:

$recipient = $this->container->getParameter( 'my_nice_project.contact_email' );

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

对于寻找类似但从服务中获取配置的读者来说,甚至有一种更好的方法,它永远不会弄乱“参数”公共空间,甚至不需要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' ] ) );
    }
}

然后在你的services.yml你像往常一样定义你的服务,没有任何绝对的改变:

services:
    my.niceproject.sillymanager:
        class: My\NiceProjectBundle\Model\SillyManager
        arguments: []

然后在你的SillyManager类中,添加方法:

class SillyManager
{
    private $contact_email;

    public function setConfig( $newConfigContactEmail )
    {
        $this->contact_email = $newConfigContactEmail;
    }
}

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

my_nice_project:
    amqp:
        host: 192.168.33.55
        user: guest
        password: guest

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

$sillyServiceDefintion->addMethodCall( 'setConfig', array( $processedConfig[ 'amqp' ] ) );

然后在服务中做:

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

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

希望这可以帮助!

于 2014-03-24T01:06:28.370 回答
36

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

# config.yml
... 
framework:
    session:
        domain: 'localhost'
...

$this->container->parameters['session.storage.options']['domain'];

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

于 2012-08-07T22:13:22.507 回答
16

为了能够为您的捆绑软件公开一些配置参数,您应该查阅相关文档。这很容易做到:)

这是链接:如何公开捆绑包的语义配置

于 2013-04-15T12:37:57.090 回答
7

就像之前所说的 - 您可以通过使用注入容器并使用其参数属性来访问任何参数。

“Symfony - 使用容器服务定义”是一篇关于它的好文章。

于 2012-10-01T20:23:02.857 回答
3

我从http://tutorial.symblog.co.uk/的代码示例中学到了一个简单的方法

1) 注意 ZendeskBlueFormBundle 和文件位置

# myproject/app/config/config.yml

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: @ZendeskBlueFormBundle/Resources/config/config.yml }

framework:

2) 通知 Zendesk_BlueForm.emails.contact_email 和文件位置

# myproject/src/Zendesk/BlueFormBundle/Resources/config/config.yml

parameters:
    # Zendesk contact email address
    Zendesk_BlueForm.emails.contact_email: dunnleaddress@gmail.com

3)注意我如何在 $client 和控制器的文件位置中获取它

# myproject/src/Zendesk/BlueFormBundle/Controller/PageController.php

    public function blueFormAction($name, $arg1, $arg2, $arg3, Request $request)
    {
    $client = new ZendeskAPI($this->container->getParameter("Zendesk_BlueForm.emails.contact_email"));
    ...
    }
于 2014-11-16T02:08:49.307 回答