I have a parameters file in an application using symfony 3.2 console, config and YAML component , and i try to set external Parameters from environment variable in the Service Container parameters.
I create container builder.
$container = new ContainerBuilder();
Am using file locator to locate resources :
$container = new ContainerBuilder();
Loader resolver to load resources
LoaderResolver();
And using load method :
$this->load('parameters.yml');
parameters.yml file:
parameters:
database:
driver: pdo_mysql
host: 127.0.0.1
dbname: dbname
user: env(VAL1)
password: env(VAL2)
Local: us-en
After compiling the container and try to check get values from parameters bag :
$container->getParameterBag()->all()
its return me values like this :
env_VAL1_3ec776edc429c1734ed780a29a0af538 , env_VAL2_3ec776edc429c1734ed780a29a0af538
I think the container can't resolve those values from the environment .
Note : i set the environment variable using :
$ export VAL1='SOME TEXT'
Anyone has an idea why ?
So I've spent some time investigating this 'issue' and here is what I found out...
The only way to get env(VAL1)
thingy working is to generate the container to PHP file using PHPDumper
and then use the generated container. There is no other way to make it working because it only resolves environment in that file.
In the normal Symfony project there is a generated var/cache/dev/appDevDebugProjectContainer.php
file. There is method getDynamicParameter
which looks like this
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;
}
It is the only place where the env(VAL1)
is evaluated.
So for your case the solution is the following.
I used simplified parameters.yml
:
parameters:
user: '%env(VAL1)%'
The export
I did:
export VAL1=abc
PHP code:
$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'
In the generated code you'll see the following method that do the magic
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;
}
This solution works fine but looking at it I wonder if this is really needed in your project? What's wrong with getenv()
?
Please try:
parameters:
database:
driver: pdo_mysql
host: 127.0.0.1
dbname: dbname
user: '%env(VAL1)%'
password: '%env(VAL2)%'
log_path: /logs
I think that's the problem. See this documentation for reference: http://symfony.com/doc/current/configuration/external_parameters.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With