diff --git a/Container.php b/Container.php index 2b9eeb84c..dd7bc6bf2 100644 --- a/Container.php +++ b/Container.php @@ -373,13 +373,9 @@ protected function getEnv(string $name): mixed $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/EnvVarProcessorInterface.php b/EnvVarProcessorInterface.php index c5366e01b..fecd47407 100644 --- a/EnvVarProcessorInterface.php +++ b/EnvVarProcessorInterface.php @@ -24,6 +24,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(string): mixed $getEnv A closure that allows fetching more env vars * diff --git a/Tests/ContainerTest.php b/Tests/ContainerTest.php index aadbdb48a..e4b368c24 100644 --- a/Tests/ContainerTest.php +++ b/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 @@ -404,6 +406,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