Загрузка параметров внешней среды в Symfony 3.2 с помощью env () во время выполнения возвращает нерешенные значения

У меня есть файл параметров в приложении с использованием symfony 3.2 console, config и YAML-компонента , и я пытаюсь установить внешние параметры из переменной среды в параметрах Service Container.

Я создаю конструктор контейнеров.

$container = new ContainerBuilder(); 

Я использую локатор файлов для поиска ресурсов:

 $container = new ContainerBuilder(); 

Преобразователь загрузчика для загрузки ресурсов

 LoaderResolver(); 

И используя метод загрузки:

 $this->load('parameters.yml'); 

Файл parameters.yml:

 parameters: database: driver: pdo_mysql host: 127.0.0.1 dbname: dbname user: env(VAL1) password: env(VAL2) Local: us-en 

После компиляции контейнера и попробуйте проверить значения из пакета параметров:

 $container->getParameterBag()->all() 

он возвращает мне такие значения:

env_VAL1_3ec776edc429c1734ed780a29a0af538 , env_VAL2_3ec776edc429c1734ed780a29a0af538

Я думаю, что контейнер не может разрешить эти значения из среды.

Примечание: я устанавливаю переменную среды, используя:

 $ export VAL1='SOME TEXT' 

У кого-нибудь есть идея, почему?

Поэтому я потратил некоторое время на изучение этой «проблемы», и вот что я узнал …

Единственный способ заставить env(VAL1) работать – создать контейнер в PHP-файл с помощью PHPDumper а затем использовать созданный контейнер. Нет другого способа заставить его работать, потому что он разрешает только среду в этом файле.

В обычном проекте Symfony создается сгенерированный файл var/cache/dev/appDevDebugProjectContainer.php . Существует метод getDynamicParameter который выглядит так:

  private function getDynamicParameter($name) { switch ($name) { case 'kernel.root_dir': $value = ($this->targetDirs[3].'/app'); break; case 'kernel.logs_dir': $value = ($this->targetDirs[2].'/logs'); break; case 'user': $value = $this->getEnv('VAL1'); break; case 'session.save_path': $value = ($this->targetDirs[3].'/app/../var/sessions/dev'); break; case 'router.resource': $value = ($this->targetDirs[3].'/app/config/routing_dev.yml'); break; default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); } $this->loadedDynamicParameters[$name] = true; return $this->dynamicParameters[$name] = $value; } 

Это единственное место, где оценивается env(VAL1) .

Итак, для вашего случая решение следующее.

Я использовал упрощенные parameters.yml :

 parameters: user: '%env(VAL1)%' 

export я сделал:

 export VAL1=abc 

PHP-код:

 $container = new ContainerBuilder(); $loader = new YamlFileLoader( $container, new FileLocator('.') ); $loader->load('parameters.yml'); $container->compile(); $dumper = new PhpDumper($container); $content = $dumper->dump( [ 'class' => 'DumpedContainer', 'base_class' => 'Container', 'file' => 'DumpedContainer.php', 'debug' => true ] ); // Use this code if you want to write file to the disk $cache = new ConfigCache('DumpedContainer.php', true); $cache->write($content, $container->getResources()); require_once $cache->getPath(); // ... otherwise use this code //$content = str_replace('<?php', '', $content); //eval($content); $container = new DumpedContainer(); $user = $container->getParameter('user'); // $user = 'abc' 

В сгенерированном коде вы увидите следующий метод, который делает магию

 private function getDynamicParameter($name) { switch ($name) { case 'user': $value = $this->getEnv('VAL1'); break; default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); } $this->loadedDynamicParameters[$name] = true; return $this->dynamicParameters[$name] = $value; } 

Это решение прекрасно работает, но, глядя на него, я задаюсь вопросом, действительно ли это необходимо в вашем проекте? Что случилось с getenv() ?

Пожалуйста попробуйте:

 parameters: database: driver: pdo_mysql host: 127.0.0.1 dbname: dbname user: '%env(VAL1)%' password: '%env(VAL2)%' log_path: /logs 

Я думаю, что это проблема. См. Эту документацию для справки: http://symfony.com/doc/current/configuration/external_parameters.html

Если вы используете Symfony \ Bundle \ FrameworkBundle \ Test \ WebTestCase вместо \ PHPUnit_Framework_TestCase Symfony3, сделайте волшебство для вас.

 $client = static::createClient(); $this->container = $client->getContainer(); $user = $container->getParameter('user'); // $user = 'abc' 

взгляните на http://symfony.com/doc/current/testing.html#your-first-functional-test

С помощью этого метода вы сможете настроить также конфигурацию Symfony, используя * _test.yml конкретные файлы.

Я думаю, что это правильный путь.