如何从symfony2的控制器中的parameter.yml中读取信息?


146

我在我的app / config / parameters.yml中放了几个自定义变量。

parameters:
    api_pass: apipass
    api_user: apiuser

我需要从我的控制器访问这些文件,并尝试使用

$this->get('api_user');

从我的控制器文件中。尝试此操作时,出现以下错误消息:

You have requested a non-existent service "api_user".

正确的方法是什么?

Answers:


296

Symfony 2.6和更早的版本中,要在控制器中获取参数-您应首先获取容器,然后获取所需的参数。

$this->container->getParameter('api_user');

文档章节对此进行了说明。

$this->get()在一个控制器的方法将加载一个服务(DOC

Symfony 2.7和更高版本中,要在控制器中获取参数,可以使用以下命令:

$this->getParameter('api_user');

3
请注意,get控制器中的方法也使用容器,但是它只能从容器获取服务,而不能从参数获取服务。您需要getParameter获取参数。
Wouter J

当我尝试时出现$this->getContainer()->getParameter('api_user');致命错误:调用未定义的方法..Longpath .. \ Controller :: getContainer()。
Bohr

1
@Bohr抱歉,不同版本的Symfony2。我已经编辑了答案-现在检查;)
Vitalii Zurian


Symfony 2.7及更高版本:$this->hasParameter()尚无法使用。
Saman Mohamadi

23

清洁之路-2018 +,Symfony 3.4+

自2017年和Symfony 3.3 + 3.4起,存在更简洁的方法-易于设置和使用。

您可以通过其构造函数将参数传递给类,而不是使用容器和服务/参数定位符反模式。不用担心,这不是耗时的工作,而是只需设置一次,然后忘记方法。

如何分两步设置?

1。 app/config/services.yml

# config.yml

# config.yml
parameters:
    api_pass: 'secret_password'
    api_user: 'my_name'

services:
    _defaults:
        autowire: true
        bind:
            $apiPass: '%api_pass%'
            $apiUser: '%api_user%'

    App\:
        resource: ..

2.任何 Controller

<?php declare(strict_types=1);

final class ApiController extends SymfonyController
{
    /**
     * @var string 
     */
    private $apiPass;

    /**
     * @var string
     */
    private $apiUser;

    public function __construct(string $apiPass, string $apiUser)
    {
        $this->apiPass = $apiPass;
        $this->apiUser = $apiUser;
    }

    public function registerAction(): void
    {
        var_dump($this->apiPass); // "secret_password"
        var_dump($this->apiUser); // "my_name"
    }
}

即时升级就绪!

如果您使用较旧的方法,则可以使用Rector使其自动化

阅读更多

这称为服务定位器上的构造函数注入方法。

要了解有关此内容的更多信息,请查看我的文章如何以简洁的方式在Symfony Controller中获取参数

(它已经过测试,我会针对新的Symfony主版本(5、6 ...)进行更新)。


关于这个主题的新简约方式:tomasvotruba.cz/blog/2018/11/05/...
托马什Votruba

10

我给你发了一个swiftmailer的例子:

parameters.yml

recipients: [email1, email2, email3]

服务:

your_service_name:
        class: your_namespace
        arguments: ["%recipients%"]

服务类别:

protected $recipients;

public function __construct($recipients)
{
    $this->recipients = $recipients;
}

8

在Symfony 4中,您可以使用ParameterBagInterface

use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

class MessageGenerator
{
    private $params;

    public function __construct(ParameterBagInterface $params)
    {
        $this->params = $params;
    }

    public function someMethod()
    {
        $parameterValue = $this->params->get('parameter_name');
        // ...
    }
}

并在app/config/services.yaml

parameters:
    locale: 'en'
    dir: '%kernel.project_dir%'

它对控制器和表单类都适用。可以在Symfony博客中找到更多详细信息


1
传递整个参数包就像传递整个容器一样。这使得只有在“如果一些特定的服务需要大量的集装箱参数”(从邮报)感
托马什Votruba

那么,您是说通过整个参数会导致性能问题吗?
ghazaleh javaheri

这是原因之一,但主要是出于可读性。如果我看到的参数名$meetupApiKey我知道会发生什么比略好于$parameterBag
托马什Votruba


0

在Symfony 4.3.1中,我使用以下命令:

services.yaml

HTTP_USERNAME: 'admin'
HTTP_PASSWORD: 'password123'

FrontController.php

$username = $this->container->getParameter('HTTP_USERNAME');
$password = $this->container->getParameter('HTTP_PASSWORD');

在4.8中不起作用。您确定有一天能正常工作吗?
里卡多·马丁斯

我真的忘记了这一点,但是可以,因为我只发布了经过测试的内容,所以它可能起作用了!
阿赫拉夫

1
抱歉,阿查拉夫。我不知道,但是在我的控制器中不起作用。在控制器内部,您可以直接调用getParameter,而无需DI。即:$this->getParameter('foo')。这就是我使它在SF 4.8中起作用的方法。
里卡多·马丁斯

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.