From 2ab8538dd1c4ae3dd68b7b885e826a180e8fedc4 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sat, 29 Nov 2025 13:04:52 -0500 Subject: [PATCH 01/10] proxy attribute --- src/Illuminate/Container/Attributes/Proxy.php | 10 +++++++++ src/Illuminate/Container/Container.php | 8 ++++++- tests/Container/ContainerTest.php | 22 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/Illuminate/Container/Attributes/Proxy.php diff --git a/src/Illuminate/Container/Attributes/Proxy.php b/src/Illuminate/Container/Attributes/Proxy.php new file mode 100644 index 000000000000..8d7d82baca7c --- /dev/null +++ b/src/Illuminate/Container/Attributes/Proxy.php @@ -0,0 +1,10 @@ + $concrete + * @param array $withoutLazyFor * @return TClass * * @throws \Illuminate\Contracts\Container\BindingResolutionException * @throws \Illuminate\Contracts\Container\CircularDependencyException */ - public function build($concrete) + public function build($concrete, $withoutLazyFor = []) { // If the concrete type is actually a Closure, we will just execute it and // hand back the results of the functions, which allows functions to be @@ -1163,6 +1165,10 @@ public function build($concrete) return $instance; } + if (! in_array($concrete, $withoutLazyFor) && ! empty($reflector->getAttributes(Proxy::class))) { + return proxy($concrete, fn () => $this->build($concrete, [$concrete])); + } + $dependencies = $constructor->getParameters(); // Once we have all the constructor's parameters we can create each of the diff --git a/tests/Container/ContainerTest.php b/tests/Container/ContainerTest.php index d5dad019ea28..21b6c83199ce 100755 --- a/tests/Container/ContainerTest.php +++ b/tests/Container/ContainerTest.php @@ -4,6 +4,7 @@ use Attribute; use Illuminate\Container\Attributes\Bind; +use Illuminate\Container\Attributes\Proxy; use Illuminate\Container\Attributes\Scoped; use Illuminate\Container\Attributes\Singleton; use Illuminate\Container\Container; @@ -13,6 +14,7 @@ use Illuminate\Contracts\Container\SelfBuilding; use PHPUnit\Framework\TestCase; use Psr\Container\ContainerExceptionInterface; +use ReflectionClass; use stdClass; use TypeError; @@ -224,6 +226,16 @@ public function testNestedDependencyResolution() $this->assertInstanceOf(ContainerImplementationStub::class, $class->inner->impl); } + public function testLazyObjects() + { + $container = new Container; + $container->bind(IContainerContractStub::class, ContainerImplementationStub::class); + $class = $container->make(ProxyDependenciesClass::class); + $this->assertTrue((new ReflectionClass($class))->isUninitializedLazyObject($class)); + $class->stubby; + $this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class)); + } + public function testContainerIsPassedToResolvers() { $container = new Container; @@ -1217,3 +1229,13 @@ public function __construct() $this->userId = $_SERVER['__withFactory.userId']; } } + +#[Proxy] +class ProxyDependenciesClass +{ + public function __construct( + public IContainerContractStub $stubby + ) { + //dd('i have been constructed!'); + } +} From 5a5982c4c08db9b2027a77d5aee115513c6c0c16 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sat, 29 Nov 2025 13:21:43 -0500 Subject: [PATCH 02/10] rename to Lazy --- .../Container/Attributes/{Proxy.php => Lazy.php} | 2 +- src/Illuminate/Container/Container.php | 4 ++-- tests/Container/ContainerTest.php | 12 ++++++++---- 3 files changed, 11 insertions(+), 7 deletions(-) rename src/Illuminate/Container/Attributes/{Proxy.php => Lazy.php} (92%) diff --git a/src/Illuminate/Container/Attributes/Proxy.php b/src/Illuminate/Container/Attributes/Lazy.php similarity index 92% rename from src/Illuminate/Container/Attributes/Proxy.php rename to src/Illuminate/Container/Attributes/Lazy.php index 8d7d82baca7c..cc9c8694ab4c 100644 --- a/src/Illuminate/Container/Attributes/Proxy.php +++ b/src/Illuminate/Container/Attributes/Lazy.php @@ -5,6 +5,6 @@ use Attribute; #[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_CLASS)] -class Proxy +class Lazy { } diff --git a/src/Illuminate/Container/Container.php b/src/Illuminate/Container/Container.php index 3ea561789654..2372f7937e6c 100755 --- a/src/Illuminate/Container/Container.php +++ b/src/Illuminate/Container/Container.php @@ -6,7 +6,7 @@ use Closure; use Exception; use Illuminate\Container\Attributes\Bind; -use Illuminate\Container\Attributes\Proxy; +use Illuminate\Container\Attributes\Lazy; use Illuminate\Container\Attributes\Scoped; use Illuminate\Container\Attributes\Singleton; use Illuminate\Contracts\Container\BindingResolutionException; @@ -1165,7 +1165,7 @@ public function build($concrete, $withoutLazyFor = []) return $instance; } - if (! in_array($concrete, $withoutLazyFor) && ! empty($reflector->getAttributes(Proxy::class))) { + if (! in_array($concrete, $withoutLazyFor) && ! empty($reflector->getAttributes(Lazy::class))) { return proxy($concrete, fn () => $this->build($concrete, [$concrete])); } diff --git a/tests/Container/ContainerTest.php b/tests/Container/ContainerTest.php index 21b6c83199ce..211446aa04b6 100755 --- a/tests/Container/ContainerTest.php +++ b/tests/Container/ContainerTest.php @@ -4,7 +4,7 @@ use Attribute; use Illuminate\Container\Attributes\Bind; -use Illuminate\Container\Attributes\Proxy; +use Illuminate\Container\Attributes\Lazy; use Illuminate\Container\Attributes\Scoped; use Illuminate\Container\Attributes\Singleton; use Illuminate\Container\Container; @@ -232,7 +232,7 @@ public function testLazyObjects() $container->bind(IContainerContractStub::class, ContainerImplementationStub::class); $class = $container->make(ProxyDependenciesClass::class); $this->assertTrue((new ReflectionClass($class))->isUninitializedLazyObject($class)); - $class->stubby; + $this->assertTrue($class->stubbyIsSet()); $this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class)); } @@ -1230,12 +1230,16 @@ public function __construct() } } -#[Proxy] +#[Lazy] class ProxyDependenciesClass { public function __construct( public IContainerContractStub $stubby ) { - //dd('i have been constructed!'); + } + + public function stubbyIsSet(): bool + { + return isset($this->stubby); } } From 76c0650b58c83c544e0ac6f43df5b07f89ab572d Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sat, 29 Nov 2025 13:40:46 -0500 Subject: [PATCH 03/10] use as contextual attribute as well --- src/Illuminate/Container/Attributes/Lazy.php | 12 ++++++-- src/Illuminate/Container/Container.php | 8 ++++-- tests/Container/ContainerTest.php | 29 ++++++++++++++++++-- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/Illuminate/Container/Attributes/Lazy.php b/src/Illuminate/Container/Attributes/Lazy.php index cc9c8694ab4c..b82475d7f692 100644 --- a/src/Illuminate/Container/Attributes/Lazy.php +++ b/src/Illuminate/Container/Attributes/Lazy.php @@ -3,8 +3,16 @@ namespace Illuminate\Container\Attributes; use Attribute; +use Illuminate\Contracts\Container\Container; +use Illuminate\Contracts\Container\ContextualAttribute; +use ReflectionNamedType; +use ReflectionParameter; -#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_CLASS)] -class Lazy +#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_CLASS | Attribute::TARGET_PARAMETER)] +class Lazy implements ContextualAttribute { + public static function resolve(self $attribute, Container $container, ReflectionNamedType $type) + { + return proxy($type->getName(), fn () => $container->make($type->getName())); + } } diff --git a/src/Illuminate/Container/Container.php b/src/Illuminate/Container/Container.php index 2372f7937e6c..7405a133cd4e 100755 --- a/src/Illuminate/Container/Container.php +++ b/src/Illuminate/Container/Container.php @@ -20,6 +20,7 @@ use ReflectionClass; use ReflectionException; use ReflectionFunction; +use ReflectionNamedType; use ReflectionParameter; use TypeError; @@ -1243,8 +1244,9 @@ protected function resolveDependencies(array $dependencies) $result = null; + // if (! is_null($attribute = Util::getContextualAttributeFromDependency($dependency))) { - $result = $this->resolveFromAttribute($attribute); + $result = $this->resolveFromAttribute($attribute, $dependency->getType()); } // If the class is null, it means the dependency is a string or some other @@ -1395,7 +1397,7 @@ protected function resolveVariadicClass(ReflectionParameter $parameter) * @param \ReflectionAttribute $attribute * @return mixed */ - public function resolveFromAttribute(ReflectionAttribute $attribute) + public function resolveFromAttribute(ReflectionAttribute $attribute, ?ReflectionNamedType $type = null) { $handler = $this->contextualAttributes[$attribute->getName()] ?? null; @@ -1409,7 +1411,7 @@ public function resolveFromAttribute(ReflectionAttribute $attribute) throw new BindingResolutionException("Contextual binding attribute [{$attribute->getName()}] has no registered handler."); } - return $handler($instance, $this); + return $handler($instance, $this, $type); } /** diff --git a/tests/Container/ContainerTest.php b/tests/Container/ContainerTest.php index 211446aa04b6..c278ff1a224b 100755 --- a/tests/Container/ContainerTest.php +++ b/tests/Container/ContainerTest.php @@ -236,6 +236,17 @@ public function testLazyObjects() $this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class)); } + public function testObjectWithLazyDependencies() + { + $container = new Container; + $container->bind(IContainerContractStub::class, ContainerImplementationStub::class); + $class = $container->make(ClassWithLazyDependencies::class); + $this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class)); + $this->assertTrue((new ReflectionClass(ContainerDependentStub::class))->isUninitializedLazyObject($class->stubby)); + $this->assertTrue($class->stubbyIsSet()); + $this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class)); + } + public function testContainerIsPassedToResolvers() { $container = new Container; @@ -1121,9 +1132,7 @@ class WildcardConcrete implements WildcardOnlyInterface { } -/* - * The order of these attributes matters because we want to ensure we only fallback to '*' when there's no more specific environment. - */ +// The order of these attributes matters because we want to ensure we only fallback to '*' when there's no more specific environment. #[Bind(FallbackConcrete::class)] #[Bind(ProdConcrete::class, environments: 'prod')] interface WildcardAndProdInterface @@ -1243,3 +1252,17 @@ public function stubbyIsSet(): bool return isset($this->stubby); } } + +class ClassWithLazyDependencies +{ + public function __construct( + #[Lazy] + public ContainerDependentStub $stubby + ) { + } + + public function stubbyIsSet(): bool + { + return isset($this->stubby); + } +} From 530e21deb9b7c6506ed49d99a8e477b876803fce Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sat, 29 Nov 2025 13:56:30 -0500 Subject: [PATCH 04/10] skipping --- tests/Container/ContainerTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/Container/ContainerTest.php b/tests/Container/ContainerTest.php index c278ff1a224b..5b2354b60b44 100755 --- a/tests/Container/ContainerTest.php +++ b/tests/Container/ContainerTest.php @@ -228,6 +228,10 @@ public function testNestedDependencyResolution() public function testLazyObjects() { + if (version_compare(phpversion(), '8.4.0', '<')) { + $this->markTestSkipped(); + } + $container = new Container; $container->bind(IContainerContractStub::class, ContainerImplementationStub::class); $class = $container->make(ProxyDependenciesClass::class); @@ -238,6 +242,10 @@ public function testLazyObjects() public function testObjectWithLazyDependencies() { + if (version_compare(phpversion(), '8.4.0', '<')) { + $this->markTestSkipped(); + } + $container = new Container; $container->bind(IContainerContractStub::class, ContainerImplementationStub::class); $class = $container->make(ClassWithLazyDependencies::class); From 53905ecbfa497890c12e1c70f45212a1b8d46fcf Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sun, 30 Nov 2025 07:33:31 -0500 Subject: [PATCH 05/10] proper target --- src/Illuminate/Container/Attributes/Lazy.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Container/Attributes/Lazy.php b/src/Illuminate/Container/Attributes/Lazy.php index b82475d7f692..0595ecb0778d 100644 --- a/src/Illuminate/Container/Attributes/Lazy.php +++ b/src/Illuminate/Container/Attributes/Lazy.php @@ -6,13 +6,12 @@ use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Container\ContextualAttribute; use ReflectionNamedType; -use ReflectionParameter; -#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_CLASS | Attribute::TARGET_PARAMETER)] +#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_PARAMETER)] class Lazy implements ContextualAttribute { public static function resolve(self $attribute, Container $container, ReflectionNamedType $type) { - return proxy($type->getName(), fn () => $container->make($type->getName())); + return proxy($type->getName(), static fn () => $container->make($type->getName())); } } From e7f48eb219a0f4363a1600a4d6dbc3f2ee6daa42 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Tue, 2 Dec 2025 06:47:57 -0500 Subject: [PATCH 06/10] more tests --- tests/Container/ContainerTest.php | 156 ++++++++++++++++++++++++------ 1 file changed, 126 insertions(+), 30 deletions(-) diff --git a/tests/Container/ContainerTest.php b/tests/Container/ContainerTest.php index 5b2354b60b44..8eda1123c064 100755 --- a/tests/Container/ContainerTest.php +++ b/tests/Container/ContainerTest.php @@ -226,35 +226,6 @@ public function testNestedDependencyResolution() $this->assertInstanceOf(ContainerImplementationStub::class, $class->inner->impl); } - public function testLazyObjects() - { - if (version_compare(phpversion(), '8.4.0', '<')) { - $this->markTestSkipped(); - } - - $container = new Container; - $container->bind(IContainerContractStub::class, ContainerImplementationStub::class); - $class = $container->make(ProxyDependenciesClass::class); - $this->assertTrue((new ReflectionClass($class))->isUninitializedLazyObject($class)); - $this->assertTrue($class->stubbyIsSet()); - $this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class)); - } - - public function testObjectWithLazyDependencies() - { - if (version_compare(phpversion(), '8.4.0', '<')) { - $this->markTestSkipped(); - } - - $container = new Container; - $container->bind(IContainerContractStub::class, ContainerImplementationStub::class); - $class = $container->make(ClassWithLazyDependencies::class); - $this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class)); - $this->assertTrue((new ReflectionClass(ContainerDependentStub::class))->isUninitializedLazyObject($class->stubby)); - $this->assertTrue($class->stubbyIsSet()); - $this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class)); - } - public function testContainerIsPassedToResolvers() { $container = new Container; @@ -945,6 +916,73 @@ public function testWithFactoryHasDependency() $this->assertEquals('taylor@laravel.com', $r->email); } + public function testLazyObjects() + { + if (version_compare(phpversion(), '8.4.0', '<')) { + $this->markTestSkipped('Lazy objects are only available in 8.4 and later'); + } + + $container = new Container; + $container->bind(IContainerContractStub::class, ContainerImplementationStub::class); + $class = $container->make(ProxyDependenciesClass::class); + $this->assertTrue((new ReflectionClass($class))->isUninitializedLazyObject($class)); + $this->assertTrue($class->stubbyIsSet()); + $this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class)); + } + + public function testObjectWithLazyDependencies() + { + if (version_compare(phpversion(), '8.4.0', '<')) { + $this->markTestSkipped('Lazy objects are only available in 8.4 and later'); + } + + $container = new Container; + $container->bind(IContainerContractStub::class, ContainerImplementationStub::class); + $class = $container->make(ClassWithLazyDependencies::class); + $this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class)); + $this->assertTrue((new ReflectionClass(ContainerDependentStub::class))->isUninitializedLazyObject($class->stubby)); + $this->assertTrue($class->stubbyIsSet()); + $this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class)); + } + + public function testLazyObjectWithLazyDependency() + { + if (version_compare(phpversion(), '8.4.0', '<')) { + $this->markTestSkipped('Lazy objects are only available in 8.4 and later'); + } + + ConstructionNotices::reset(); + + $container = new Container; + $container->bind(IContainerContractStub::class, ContainerImplementationStub::class); + + $class = $container->make(LazyClassWithLazyDependency::class); + // The object and its dependency are both lazy + $this->assertCount(0, ConstructionNotices::$constructed); + $this->assertTrue((new ReflectionClass($class))->isUninitializedLazyObject($class)); + + // Now we call a function on the object to bring its direct dependencies to life + $class->setValue('hello'); + + // And the object overall is not lazy + $this->assertCount(2, ConstructionNotices::$constructed); + $this->assertTrue(ConstructionNotices::$constructed[LazyClassWithLazyDependency::class]); + $this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class)); + // Nor is its non-lazy dependency + $this->assertTrue(ConstructionNotices::$constructed[ClassWithLazyDependencies::class]); + + // now we bring to life `$wholeClassIsLazyDependency` + $class->bringDependencyToLife('child dependency'); + $this->assertCount(4, ConstructionNotices::$constructed); + $this->assertTrue(ConstructionNotices::$constructed[ProxyDependenciesClass::class]); + // which also constructs its Container IContainerImplementationStub dependency + $this->assertTrue(ConstructionNotices::$constructed[ContainerImplementationStub::class]); + + $class->lazyAttributeDependency->bringDependencyToLife('grandchild dependency'); + $this->assertCount(5, ConstructionNotices::$constructed); + $this->assertTrue(ConstructionNotices::$constructed[ContainerDependentStub::class]); + } + // public function testContainerCanCatchCircularDependency() // { // $this->expectException(\Illuminate\Contracts\Container\CircularDependencyException::class); @@ -990,7 +1028,10 @@ interface IContainerContractStub class ContainerImplementationStub implements IContainerContractStub { - // + public function __construct() + { + ConstructionNotices::$constructed[self::class] = true; + } } class ContainerImplementationStubTwo implements IContainerContractStub @@ -1000,11 +1041,18 @@ class ContainerImplementationStubTwo implements IContainerContractStub class ContainerDependentStub { + public $value; public $impl; public function __construct(IContainerContractStub $impl) { $this->impl = $impl; + ConstructionNotices::$constructed[self::class] = true; + } + + public function setValue($value) + { + $this->value = $value; } } @@ -1250,15 +1298,23 @@ public function __construct() #[Lazy] class ProxyDependenciesClass { + public string $value; + public function __construct( public IContainerContractStub $stubby ) { + ConstructionNotices::$constructed[self::class] = true; } public function stubbyIsSet(): bool { return isset($this->stubby); } + + public function setValue(string $value): void + { + $this->value = $value; + } } class ClassWithLazyDependencies @@ -1267,10 +1323,50 @@ public function __construct( #[Lazy] public ContainerDependentStub $stubby ) { + ConstructionNotices::$constructed[self::class] = true; } public function stubbyIsSet(): bool { return isset($this->stubby); } + + public function bringDependencyToLife($value): void + { + $this->stubby->setValue($value); + } +} + +#[Lazy] +class LazyClassWithLazyDependency +{ + public string $value; + + public function __construct( + public ProxyDependenciesClass $wholeClassIsLazyDependency, + public ClassWithLazyDependencies $lazyAttributeDependency + ) { + ConstructionNotices::$constructed[self::class] = true; + } + + public function setValue(string $value): void + { + $this->value = $value; + } + + public function bringDependencyToLife(string $value): void + { + $this->wholeClassIsLazyDependency->setValue($value); + } +} + +class ConstructionNotices +{ + /** @var array */ + public static array $constructed = []; + + public static function reset(): void + { + self::$constructed = []; + } } From c1e6c578c9e59e4ca20f6da550d9cbc81d20c51c Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Tue, 2 Dec 2025 19:50:49 -0500 Subject: [PATCH 07/10] lazy singleton --- tests/Container/ContainerTest.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/Container/ContainerTest.php b/tests/Container/ContainerTest.php index 8eda1123c064..8f48229627f3 100755 --- a/tests/Container/ContainerTest.php +++ b/tests/Container/ContainerTest.php @@ -983,6 +983,31 @@ public function testLazyObjectWithLazyDependency() $this->assertTrue(ConstructionNotices::$constructed[ContainerDependentStub::class]); } + public function testLazyObjectAsSingleton() + { + if (version_compare(phpversion(), '8.4.0', '<')) { + $this->markTestSkipped('Lazy objects are only available in 8.4 and later'); + } + + ConstructionNotices::reset(); + + $container = new Container; + $container->singleton(LazyClassWithLazyDependency::class); + $class = $container->make(LazyClassWithLazyDependency::class); + + $this->assertInstanceOf(LazyClassWithLazyDependency::class, $class); + $this->assertCount(0, ConstructionNotices::$constructed); + $class2 = $container->make(LazyClassWithLazyDependency::class); + $this->assertCount(0, ConstructionNotices::$constructed); + $this->assertSame($class, $class2); + + $class->setValue('hello'); + $this->assertCount(2, ConstructionNotices::$constructed); + $this->assertTrue(ConstructionNotices::$constructed[ClassWithLazyDependencies::class]); + $this->assertTrue(ConstructionNotices::$constructed[LazyClassWithLazyDependency::class]); + $this->assertEquals('hello', $class2->value); + } + // public function testContainerCanCatchCircularDependency() // { // $this->expectException(\Illuminate\Contracts\Container\CircularDependencyException::class); From ca2b2918e3d114386a3b5ead463fc82e61e595fe Mon Sep 17 00:00:00 2001 From: Luke Kuzmish <42181698+cosmastech@users.noreply.github.com> Date: Tue, 9 Dec 2025 05:15:35 -0500 Subject: [PATCH 08/10] Update Container.php --- src/Illuminate/Container/Container.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Illuminate/Container/Container.php b/src/Illuminate/Container/Container.php index 7405a133cd4e..8acd0bd1f5b0 100755 --- a/src/Illuminate/Container/Container.php +++ b/src/Illuminate/Container/Container.php @@ -1167,7 +1167,7 @@ public function build($concrete, $withoutLazyFor = []) } if (! in_array($concrete, $withoutLazyFor) && ! empty($reflector->getAttributes(Lazy::class))) { - return proxy($concrete, fn () => $this->build($concrete, [$concrete])); + return proxy($concrete, fn () => $this->build($concrete, array_push($withoutLazyFor, $concrete))); } $dependencies = $constructor->getParameters(); @@ -1244,7 +1244,6 @@ protected function resolveDependencies(array $dependencies) $result = null; - // if (! is_null($attribute = Util::getContextualAttributeFromDependency($dependency))) { $result = $this->resolveFromAttribute($attribute, $dependency->getType()); } From 817ba2f63edb9ebaced260ea443472818dde00c8 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish <42181698+cosmastech@users.noreply.github.com> Date: Tue, 9 Dec 2025 05:16:54 -0500 Subject: [PATCH 09/10] Update ContainerTest.php --- tests/Container/ContainerTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Container/ContainerTest.php b/tests/Container/ContainerTest.php index 8f48229627f3..b5fe4dab3265 100755 --- a/tests/Container/ContainerTest.php +++ b/tests/Container/ContainerTest.php @@ -1213,7 +1213,9 @@ class WildcardConcrete implements WildcardOnlyInterface { } -// The order of these attributes matters because we want to ensure we only fallback to '*' when there's no more specific environment. +/* + * The order of these attributes matters because we want to ensure we only fallback to '*' when there's no more specific environment. + */ #[Bind(FallbackConcrete::class)] #[Bind(ProdConcrete::class, environments: 'prod')] interface WildcardAndProdInterface From f5aa6afd8da2cb19d0bcd170b4872751431140d1 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish <42181698+cosmastech@users.noreply.github.com> Date: Tue, 9 Dec 2025 05:22:08 -0500 Subject: [PATCH 10/10] Update Container.php --- src/Illuminate/Container/Container.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Container/Container.php b/src/Illuminate/Container/Container.php index 8acd0bd1f5b0..c369ff51ebb2 100755 --- a/src/Illuminate/Container/Container.php +++ b/src/Illuminate/Container/Container.php @@ -1167,7 +1167,7 @@ public function build($concrete, $withoutLazyFor = []) } if (! in_array($concrete, $withoutLazyFor) && ! empty($reflector->getAttributes(Lazy::class))) { - return proxy($concrete, fn () => $this->build($concrete, array_push($withoutLazyFor, $concrete))); + return proxy($concrete, fn () => $this->build($concrete, [...$withoutLazyFor, $concrete])); } $dependencies = $constructor->getParameters();