У меня есть файл параметров в приложении с использованием 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 конкретные файлы.
Я думаю, что это правильный путь.