diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index 235b76ef44fd1..6cb148e0ccd25 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -391,13 +391,9 @@ protected function getEnv(string $name) $localName = $name; } - if ($processors->has($prefix)) { - $processor = $processors->get($prefix); - } else { - $processor = new EnvVarProcessor($this); - if (false === $i) { - $prefix = ''; - } + $processor = $processors->has($prefix) ? $processors->get($prefix) : new EnvVarProcessor($this); + if (false === $i) { + $prefix = ''; } $this->resolving[$envName] = true; diff --git a/src/Symfony/Component/DependencyInjection/EnvVarProcessorInterface.php b/src/Symfony/Component/DependencyInjection/EnvVarProcessorInterface.php index d3275fe290e36..ee43b05672a4c 100644 --- a/src/Symfony/Component/DependencyInjection/EnvVarProcessorInterface.php +++ b/src/Symfony/Component/DependencyInjection/EnvVarProcessorInterface.php @@ -23,7 +23,7 @@ interface EnvVarProcessorInterface /** * Returns the value of the given variable as managed by the current instance. * - * @param string $prefix The namespace of the variable + * @param string $prefix The namespace of the variable; when the empty string is passed, null values should be kept as is * @param string $name The name of the variable within the namespace * @param \Closure $getEnv A closure that allows fetching more env vars * diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php index d9fa0f3790cf0..3b7510fd1a99f 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php @@ -14,11 +14,13 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\EnvVarProcessor; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\ServiceLocator; use Symfony\Contracts\Service\ResetInterface; class ContainerTest extends TestCase @@ -405,6 +407,33 @@ public function testRequestAnInternalSharedPrivateService() $c->get('internal_dependency'); $c->get('internal'); } + + public function testGetEnvDoesNotAutoCastNullWithDefaultEnvVarProcessor() + { + $container = new Container(); + $container->setParameter('env(FOO)', null); + $container->compile(); + + $r = new \ReflectionMethod($container, 'getEnv'); + $r->setAccessible(true); + $this->assertNull($r->invoke($container, 'FOO')); + } + + public function testGetEnvDoesNotAutoCastNullWithEnvVarProcessorsLocatorReturningDefaultEnvVarProcessor() + { + $container = new Container(); + $container->setParameter('env(FOO)', null); + $container->set('container.env_var_processors_locator', new ServiceLocator([ + 'string' => static function () use ($container): EnvVarProcessor { + return new EnvVarProcessor($container); + }, + ])); + $container->compile(); + + $r = new \ReflectionMethod($container, 'getEnv'); + $r->setAccessible(true); + $this->assertNull($r->invoke($container, 'FOO')); + } } class ProjectServiceContainer extends Container