diff --git a/Resources/config/web.php b/Resources/config/web.php index 17a585d58..60ceecf9f 100644 --- a/Resources/config/web.php +++ b/Resources/config/web.php @@ -83,10 +83,13 @@ ->tag('controller.argument_value_resolver', ['priority' => 100, 'name' => RequestAttributeValueResolver::class]) ->set('argument_resolver.request', RequestValueResolver::class) - ->tag('controller.argument_value_resolver', ['priority' => 50, 'name' => RequestValueResolver::class]) + // Run before EntityValueResolver (DoctrineBundle, priority 110) so type-hinted + // Request arguments do not trigger entity-manager bootstrap. Keep this above + // DoctrineBundle's EntityValueResolver priority if it ever changes. + ->tag('controller.argument_value_resolver', ['priority' => 120, 'name' => RequestValueResolver::class]) ->set('argument_resolver.session', SessionValueResolver::class) - ->tag('controller.argument_value_resolver', ['priority' => 50, 'name' => SessionValueResolver::class]) + ->tag('controller.argument_value_resolver', ['priority' => 120, 'name' => SessionValueResolver::class]) ->set('argument_resolver.service', ServiceValueResolver::class) ->args([ diff --git a/Tests/DependencyInjection/FrameworkExtensionTestCase.php b/Tests/DependencyInjection/FrameworkExtensionTestCase.php index 26f1c3f93..52d804337 100644 --- a/Tests/DependencyInjection/FrameworkExtensionTestCase.php +++ b/Tests/DependencyInjection/FrameworkExtensionTestCase.php @@ -181,6 +181,22 @@ public function testPropertyAccessCacheWithDebug() $this->assertSame(ArrayAdapter::class, $cache->getClass(), 'ArrayAdapter should be used in debug mode'); } + public function testRequestAndSessionValueResolversRunBeforeEntityValueResolver() + { + $container = $this->createContainerFromFile('full'); + + // DoctrineBundle ships EntityValueResolver at priority 110. Lower priorities trigger an + // entity-manager bootstrap on every Request/Session controller argument before the + // dedicated resolver is asked, costing tens of ms per request. + $entityValueResolverPriority = 110; + + $requestTag = $container->getDefinition('argument_resolver.request')->getTag('controller.argument_value_resolver'); + $this->assertGreaterThan($entityValueResolverPriority, $requestTag[0]['priority']); + + $sessionTag = $container->getDefinition('argument_resolver.session')->getTag('controller.argument_value_resolver'); + $this->assertGreaterThan($entityValueResolverPriority, $sessionTag[0]['priority']); + } + public function testCsrfProtectionNeedsSessionToBeEnabled() { $this->expectException(\LogicException::class);