[DI] ContainerBuilder::compile() can optionally resolve env vars in parameter bag

This commit is contained in:
Nicolas Grekas 2017-01-29 19:27:06 +01:00
parent 23ba91272f
commit a3fd512271
2 changed files with 52 additions and 2 deletions

View File

@ -25,6 +25,7 @@ use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceExce
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\Config\Resource\ClassExistenceResource;
use Symfony\Component\Config\Resource\DirectoryResource;
use Symfony\Component\Config\Resource\FileExistenceResource;
@ -657,9 +658,25 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
* * Parameter values are resolved;
* * The parameter bag is frozen;
* * Extension loading is disabled.
*
* @param bool $resolveEnvPlaceholders Whether %env()% parameters should be resolved using the current
* env vars or be replaced by uniquely identifiable placeholders.
* Set to "true" when you want to use the current ContainerBuilder
* directly, keep to "false" when the container is dumped instead.
*/
public function compile()
public function compile(/*$resolveEnvPlaceholders = false*/)
{
if (1 <= func_num_args()) {
$resolveEnvPlaceholders = func_get_arg(0);
} else {
if (__CLASS__ !== static::class) {
$r = new \ReflectionMethod($this, __FUNCTION__);
if (__CLASS__ !== $r->getDeclaringClass()->getName() && (1 > $r->getNumberOfParameters() || 'resolveEnvPlaceholders' !== $r->getParameters()[0]->name)) {
@trigger_error(sprintf('The %s::compile() method expects a first "$resolveEnvPlaceholders" argument since version 3.3. It will be made mandatory in 4.0.', static::class), E_USER_DEPRECATED);
}
}
$resolveEnvPlaceholders = false;
}
$compiler = $this->getCompiler();
if ($this->trackResources) {
@ -667,6 +684,13 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
$this->addObjectResource($pass);
}
}
$bag = $this->getParameterBag();
if ($resolveEnvPlaceholders && $bag instanceof EnvPlaceholderParameterBag) {
$this->parameterBag = new ParameterBag($this->resolveEnvPlaceholders($bag->all(), true));
$this->envPlaceholders = $bag->getEnvPlaceholders();
$this->parameterBag = $bag = new ParameterBag($this->resolveEnvPlaceholders($this->parameterBag->all()));
}
$compiler->compile($this);
@ -680,7 +704,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
}
$this->extensionConfigs = array();
$bag = $this->getParameterBag();
parent::compile();

View File

@ -550,6 +550,33 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
unset($_ENV['DUMMY_ENV_VAR']);
}
public function testCompileWithResolveEnv()
{
$_ENV['DUMMY_ENV_VAR'] = 'du%%y';
$container = new ContainerBuilder();
$container->setParameter('env(FOO)', 'Foo');
$container->setParameter('bar', '%% %env(DUMMY_ENV_VAR)%');
$container->setParameter('foo', '%env(FOO)%');
$container->compile(true);
$this->assertSame('% du%%y', $container->getParameter('bar'));
$this->assertSame('Foo', $container->getParameter('foo'));
unset($_ENV['DUMMY_ENV_VAR']);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\EnvNotFoundException
* @expectedExceptionMessage Environment variable not found: "FOO".
*/
public function testCompileWithResolveMissingEnv()
{
$container = new ContainerBuilder();
$container->setParameter('foo', '%env(FOO)%');
$container->compile(true);
}
/**
* @expectedException \LogicException
*/