diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TestServiceContainerRefPassesTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TestServiceContainerRefPassesTest.php index fc69d5bd16858..3a6824e4fc92b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TestServiceContainerRefPassesTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TestServiceContainerRefPassesTest.php @@ -33,44 +33,44 @@ public function testProcess() $container->addCompilerPass(new TestServiceContainerWeakRefPass(), PassConfig::TYPE_BEFORE_REMOVING, -32); $container->addCompilerPass(new TestServiceContainerRealRefPass(), PassConfig::TYPE_AFTER_REMOVING); - $container->register('Test\public_service') + $container->register('test.public_service', 'stdClass') ->setPublic(true) - ->addArgument(new Reference('Test\private_used_shared_service')) - ->addArgument(new Reference('Test\private_used_non_shared_service')) - ->addArgument(new Reference('Test\soon_private_service')) + ->addArgument(new Reference('test.private_used_shared_service')) + ->addArgument(new Reference('test.private_used_non_shared_service')) + ->addArgument(new Reference('test.soon_private_service')) ; - $container->register('Test\soon_private_service') + $container->register('test.soon_private_service', 'stdClass') ->setPublic(true) ->addTag('container.private', ['package' => 'foo/bar', 'version' => '1.42']) ; - $container->register('Test\soon_private_service_decorated') + $container->register('test.soon_private_service_decorated', 'stdClass') ->setPublic(true) ->addTag('container.private', ['package' => 'foo/bar', 'version' => '1.42']) ; - $container->register('Test\soon_private_service_decorator') - ->setDecoratedService('Test\soon_private_service_decorated') - ->setArguments(['Test\soon_private_service_decorator.inner']); + $container->register('test.soon_private_service_decorator', 'stdClass') + ->setDecoratedService('test.soon_private_service_decorated') + ->setArguments(['test.soon_private_service_decorator.inner']); - $container->register('Test\private_used_shared_service'); - $container->register('Test\private_unused_shared_service'); - $container->register('Test\private_used_non_shared_service')->setShared(false); - $container->register('Test\private_unused_non_shared_service')->setShared(false); + $container->register('test.private_used_shared_service', 'stdClass'); + $container->register('test.private_unused_shared_service', 'stdClass'); + $container->register('test.private_used_non_shared_service', 'stdClass')->setShared(false); + $container->register('test.private_unused_non_shared_service', 'stdClass')->setShared(false); $container->compile(); $expected = [ - 'Test\private_used_shared_service' => new ServiceClosureArgument(new Reference('Test\private_used_shared_service')), - 'Test\private_used_non_shared_service' => new ServiceClosureArgument(new Reference('Test\private_used_non_shared_service')), - 'Test\soon_private_service' => new ServiceClosureArgument(new Reference('.container.private.Test\soon_private_service')), - 'Test\soon_private_service_decorator' => new ServiceClosureArgument(new Reference('.container.private.Test\soon_private_service_decorated')), - 'Test\soon_private_service_decorated' => new ServiceClosureArgument(new Reference('.container.private.Test\soon_private_service_decorated')), + 'test.private_used_shared_service' => new ServiceClosureArgument(new Reference('test.private_used_shared_service')), + 'test.private_used_non_shared_service' => new ServiceClosureArgument(new Reference('test.private_used_non_shared_service')), + 'test.soon_private_service' => new ServiceClosureArgument(new Reference('.container.private.test.soon_private_service')), + 'test.soon_private_service_decorator' => new ServiceClosureArgument(new Reference('.container.private.test.soon_private_service_decorated')), + 'test.soon_private_service_decorated' => new ServiceClosureArgument(new Reference('.container.private.test.soon_private_service_decorated')), ]; $privateServices = $container->getDefinition('test.private_services_locator')->getArgument(0); unset($privateServices[\Symfony\Component\DependencyInjection\ContainerInterface::class], $privateServices[ContainerInterface::class]); $this->assertEquals($expected, $privateServices); - $this->assertFalse($container->getDefinition('Test\private_used_non_shared_service')->isShared()); + $this->assertFalse($container->getDefinition('test.private_used_non_shared_service')->isShared()); } } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveClassPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveClassPass.php index 4b7a2bb401570..138cca0df349c 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveClassPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveClassPass.php @@ -27,9 +27,14 @@ public function process(ContainerBuilder $container): void continue; } if (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)++$/', $id)) { - if ($definition instanceof ChildDefinition && !class_exists($id)) { - throw new InvalidArgumentException(\sprintf('Service definition "%s" has a parent but no class, and its name looks like an FQCN. Either the class is missing or you want to inherit it from the parent service. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class.', $id)); + if (!class_exists($id) && !interface_exists($id)) { + $error = $definition instanceof ChildDefinition ? + 'has a parent but no class, and its name looks like a FQCN. Either the class is missing or you want to inherit it from the parent service' : + 'name looks like a FQCN but the class does not exist'; + + throw new InvalidArgumentException("Service definition \"{$id}\" {$error}. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class."); } + $definition->setClass($id); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveClassPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveClassPassTest.php index 914115f28662a..aed2dc321c9b0 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveClassPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveClassPassTest.php @@ -35,7 +35,6 @@ public function testResolveClassFromId($serviceId) public static function provideValidClassId() { - yield ['Acme\UnknownClass']; yield [CaseSensitiveClass::class]; } @@ -62,7 +61,7 @@ public static function provideInvalidClassId() public function testNonFqcnChildDefinition() { $container = new ContainerBuilder(); - $parent = $container->register('App\Foo', null); + $parent = $container->register('App\Foo.parent', 'App\Foo'); $child = $container->setDefinition('App\Foo.child', new ChildDefinition('App\Foo')); (new ResolveClassPass())->process($container); @@ -74,7 +73,7 @@ public function testNonFqcnChildDefinition() public function testClassFoundChildDefinition() { $container = new ContainerBuilder(); - $parent = $container->register('App\Foo', null); + $parent = $container->register('foo.parent', 'App\Foo'); $child = $container->setDefinition(self::class, new ChildDefinition('App\Foo')); (new ResolveClassPass())->process($container); @@ -86,11 +85,21 @@ public function testClassFoundChildDefinition() public function testAmbiguousChildDefinition() { $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Service definition "App\Foo\Child" has a parent but no class, and its name looks like an FQCN. Either the class is missing or you want to inherit it from the parent service. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class.'); + $this->expectExceptionMessage('Service definition "App\Foo\Child" has a parent but no class, and its name looks like a FQCN. Either the class is missing or you want to inherit it from the parent service. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class.'); $container = new ContainerBuilder(); - $container->register('App\Foo', null); + $container->register('app.foo', 'App\Foo'); $container->setDefinition('App\Foo\Child', new ChildDefinition('App\Foo')); (new ResolveClassPass())->process($container); } + + public function testInvalidClassNameDefinition() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Service definition "Acme\UnknownClass" name looks like a FQCN but the class does not exist. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class.'); + $container = new ContainerBuilder(); + $container->register('Acme\UnknownClass'); + + (new ResolveClassPass())->process($container); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index f87c8ced4281d..aa932d083b41e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1546,11 +1546,9 @@ public function testClassFromId() { $container = new ContainerBuilder(); - $unknown = $container->register('Acme\UnknownClass'); $autoloadClass = $container->register(CaseSensitiveClass::class); $container->compile(); - $this->assertSame('Acme\UnknownClass', $unknown->getClass()); $this->assertEquals(CaseSensitiveClass::class, $autoloadClass->getClass()); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index a117a69a02cf8..dbba8d2826b5c 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -75,6 +75,7 @@ require_once __DIR__.'/../Fixtures/includes/classes.php'; require_once __DIR__.'/../Fixtures/includes/foo.php'; require_once __DIR__.'/../Fixtures/includes/foo_lazy.php'; +require_once __DIR__.'/../Fixtures/includes/fixture_app_services.php'; class PhpDumperTest extends TestCase { @@ -1317,7 +1318,7 @@ public function testInlineSelfRef() ->setProperty('bar', $bar) ->addArgument($bar); - $container->register('App\Foo') + $container->register('App\Foo', 'App\Foo') ->setPublic(true) ->addArgument($baz); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container33.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container33.php index 673abe204cd9e..a5f94494e6cc0 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container33.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container33.php @@ -6,7 +6,7 @@ $container = new ContainerBuilder(); -$container->register(\Foo\Foo::class)->setPublic(true); -$container->register(\Bar\Foo::class)->setPublic(true); +$container->register('Foo\Foo', \Foo\Foo::class)->setPublic(true); +$container->register('Bar\Foo', \Bar\Foo::class)->setPublic(true); return $container; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_inline_requires.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_inline_requires.php index d94a670574245..0517daef8a148 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_inline_requires.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_inline_requires.php @@ -12,6 +12,6 @@ $container->register(HotPath\C1::class)->addTag('container.hot_path')->setPublic(true); $container->register(HotPath\C2::class)->addArgument(new Reference(HotPath\C3::class))->setPublic(true); $container->register(HotPath\C3::class); -$container->register(ParentNotExists::class)->setPublic(true); +$container->register(ParentNotExists::class, ParentNotExists::class)->setPublic(true); return $container; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/fixture_app_services.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/fixture_app_services.php new file mode 100644 index 0000000000000..7e0bf5433536d --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/fixture_app_services.php @@ -0,0 +1,63 @@ +otherInstances = $otherInstances; } } + +namespace Acme; + +class Foo +{ +} + +class WithShortCutArgs +{ +} diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php index 72ededfd07329..9ca0104eaaf6c 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\DependencyInjection\Tests\Loader; require_once __DIR__.'/../Fixtures/includes/AcmeExtension.php'; +require_once __DIR__.'/../Fixtures/includes/fixture_app_services.php'; use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Builder\ConfigBuilderGenerator;
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: