Как мне прочитать параметры конфигурации из Symfony2 config.yml?

175

Я добавил параметр в свой файл config.yml как таковой:

app.config:
    contact_email: [email protected]
    ...

В моей жизни я не могу понять, как читать ее в переменную. Я попробовал что-то вроде этого в одном из моих контроллеров:

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

Но я получаю сообщение об ошибке:

Параметр "contact_email" должен быть определены.

Я очистил свой кеш, я также повсюду смотрел в документации по загрузке сайта Symfony2, но я не могу узнать, как это сделать.

Наверное, слишком устал, чтобы понять это сейчас. Может ли кто-нибудь помочь с этим?

Теги:
configuration

6 ответов

177
Лучший ответ

Вместо определения contact_email внутри app.config, определите его в записи parameters:

parameters:
    contact_email: [email protected]

Вы должны найти, что вызов, который вы делаете в своем контроллере, теперь работает.

  • 4
    Как это будет работать со средами Dev / Prod? Поэтому для тестирования я хочу, чтобы электронные письма отправлялись на тестовое электронное письмо, а производственный персонал получал бы другое электронное письмо.
  • 2
    @Phill: Если вы используете стандартный swiftmailer в вашем symfony2, вы можете использовать следующий параметр в config_dev.yml: swiftmailer: delivery_address: [email protected] Более подробную информацию вы можете найти в кулинарной книге Symfony2
Показать ещё 3 комментария
143

В то время как решение перемещать contact_email в parameters.yml легко, как предложено в других ответах, которое может легко загромождать ваш файл параметров, если вы имеете дело со многими пакетами, или если вы имеете дело с вложенными блоками конфигурации.

  • Во-первых, я точно отвечу на вопрос.
  • Позже я дам подход для получения этих конфигураций из служб, не проходя через общее пространство в качестве параметров.

ПЕРВЫЙ ПОДХОД: Разделенный блок конфигурации, получая его как параметр

С расширением (подробнее о расширениях здесь) вы можете легко "разделить" его на разные блоки в config.yml, а затем ввести в качестве параметра gettable от контроллера.

Внутри класса 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: [email protected]

Чтобы иметь возможность обрабатывать этот 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' );

ВТОРОЙ ПОДХОД: Раздельный блок конфигурации, вводя конфигурацию в службу

Для читателей, которые ищут что-то похожее, но для получения конфига из службы, есть даже более хороший способ, который никогда не загромождает общее пространство "paramaters" и даже не нуждается в передаче 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' ];
    }
}

Надеюсь, это поможет!

  • 10
    Отлично! Спасибо за подробный ответ.
  • 13
    Это должен был быть ответ!
Показать ещё 12 комментариев
33

Я должен добавить к ответу douglas, вы можете получить доступ к глобальной конфигурации, но symfony переводит некоторые параметры, например:

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

являются

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

Вы можете использовать var_dump для поиска указанного ключа или значения.

  • 0
    просто и легко! Спасибо
16

Чтобы иметь возможность отображать некоторые параметры конфигурации для вашего пакета, вы должны проконсультироваться с документацией для этого. Это довольно легко сделать:)

Здесь ссылка: Как открыть семантическую конфигурацию для пакета

  • 0
    Честно говоря, этот вопрос задавался более 2 лет назад, тогда вышеупомянутой статьи не существовало.
  • 10
    Я согласен с этим утверждением. Я установил ответ на случай, если кто-нибудь откроет эту статью в настоящее время. Спасибо за отрицательный рейтинг - вы сделали мой день.
Показать ещё 4 комментария
7

Как и раньше, вы можете получить доступ к любым параметрам с помощью контейнера для инъекций и использовать его свойство параметра.

"Symfony - работа с определениями контейнеров" - хорошая статья об этом.

2

Я легко понял из примера кода 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: [email protected]

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"));
    ...
    }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню