Skip to content

Commit 9af8af8

Browse files
committed
Allow recursive container calls from factory functions for variables
1 parent 40381d8 commit 9af8af8

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

src/Container.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -395,17 +395,15 @@ private function loadVariable(string $name, int $depth = 64) /*: object|string|i
395395
\assert($factory instanceof \Closure);
396396
$closure = new \ReflectionFunction($factory);
397397

398-
// build list of factory parameters based on parameter types
398+
// invoke factory with list of parameters
399399
// temporarily unset factory reference to allow loading recursive variables from environment
400400
try {
401401
unset($this->container[$name]);
402-
$params = $this->loadFunctionParams($closure, $depth - 1, true, '$' . $name);
402+
$value = $factory(...$this->loadFunctionParams($closure, $depth - 1, true, '$' . $name));
403403
} finally {
404404
$this->container[$name] = $factory;
405405
}
406406

407-
// invoke factory with list of parameters
408-
$value = $factory(...$params);
409407
if (!\is_object($value) && !\is_scalar($value) && $value !== null) {
410408
throw new \TypeError(
411409
'Return value of ' . self::functionName($closure) . ' for $' . $name . ' must be of type object|string|int|float|bool|null, ' . $this->gettype($value) . ' returned'

tests/ContainerTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2126,6 +2126,28 @@ public function testGetEnvReturnsStringFromRecursiveFactoryWithDefaultValueIfNot
21262126
$this->assertEquals('foo', $container->getEnv('X_FOO'));
21272127
}
21282128

2129+
public function testGetEnvReturnsNullIfFactoryFunctionUsesRecursiveGetEnvForVariableNotSetInGlobalEnv(): void
2130+
{
2131+
$container = new Container([
2132+
'X_FOO' => function (Container $container) { return $container->getEnv('X_FOO'); }
2133+
]);
2134+
2135+
$this->assertNull($container->getEnv('X_FOO'));
2136+
}
2137+
2138+
public function testGetEnvReturnsStringIfFactoryFunctionUsesRecursiveGetEnvForVariableSetInGlobalEnv(): void
2139+
{
2140+
$container = new Container([
2141+
'X_FOO' => function (Container $container) { return $container->getEnv('X_FOO'); }
2142+
]);
2143+
2144+
$_ENV['X_FOO'] = 'foo';
2145+
$ret = $container->getEnv('X_FOO');
2146+
unset($_ENV['X_FOO']);
2147+
2148+
$this->assertEquals('foo', $ret);
2149+
}
2150+
21292151
public function testGetEnvReturnsStringFromPsrContainer(): void
21302152
{
21312153
$psr = $this->createMock(ContainerInterface::class);

0 commit comments

Comments
 (0)