Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c539899

Browse filesBrowse files
[HttpKernel][DI] allow bundles to declare classes that should be preloaded
1 parent b00b633 commit c539899
Copy full SHA for c539899

File tree

13 files changed

+407
-109
lines changed
Filter options

13 files changed

+407
-109
lines changed

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+52Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,37 @@ public function load(array $configs, ContainerBuilder $container)
453453

454454
$container->registerForAutoconfiguration(RouteLoaderInterface::class)
455455
->addTag('routing.route_loader');
456+
457+
$this->addClassesToPreload([
458+
'Psr\Log\LogLevel',
459+
'Symfony\Component\Cache\Adapter\ApcuAdapter',
460+
'Symfony\Component\Cache\Adapter\ArrayAdapter',
461+
'Symfony\Component\Cache\Adapter\PhpArrayAdapter',
462+
'Symfony\Component\Cache\Adapter\PhpFilesAdapter',
463+
'Symfony\Component\Cache\CacheItem',
464+
'Symfony\Component\DependencyInjection\Argument\RewindableGenerator',
465+
'Symfony\Component\DependencyInjection\Argument\ServiceLocator',
466+
'Symfony\Component\DependencyInjection\ContainerAwareInterface',
467+
'Symfony\Component\DependencyInjection\ContainerAwareTrait',
468+
'Symfony\Component\Dotenv\Dotenv',
469+
'Symfony\Component\ErrorHandler\ErrorHandler',
470+
'Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy',
471+
'Symfony\Component\HttpFoundation\AcceptHeader',
472+
'Symfony\Component\HttpFoundation\AcceptHeaderItem',
473+
'Symfony\Component\HttpFoundation\FileBag',
474+
'Symfony\Component\HttpFoundation\HeaderBag',
475+
'Symfony\Component\HttpFoundation\HeaderUtils',
476+
'Symfony\Component\HttpFoundation\ParameterBag',
477+
'Symfony\Component\HttpFoundation\ResponseHeaderBag',
478+
'Symfony\Component\HttpFoundation\ServerBag',
479+
'Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent',
480+
'Symfony\Component\HttpKernel\Event\ControllerEvent',
481+
'Symfony\Component\HttpKernel\Event\TerminateEvent',
482+
'Symfony\Component\HttpKernel\KernelEvents',
483+
'Symfony\Component\VarExporter\Internal\Hydrator',
484+
'Symfony\Component\VarExporter\Internal\Registry',
485+
'Symfony\Component\WebLink\HttpHeaderSerializer',
486+
]);
456487
}
457488

458489
/**
@@ -850,6 +881,15 @@ private function registerRouterConfiguration(array $config, ContainerBuilder $co
850881

851882
$loader->load('routing.xml');
852883

884+
$this->addClassesToPreload([
885+
'Symfony\Bundle\FrameworkBundle\Routing\RedirectableCompiledUrlMatcher',
886+
'Symfony\Component\Routing\Annotation\Route',
887+
'Symfony\Component\Routing\Matcher\CompiledUrlMatcher',
888+
'Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait',
889+
'Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface',
890+
'Symfony\Component\Routing\Matcher\UrlMatcher',
891+
]);
892+
853893
if ($config['utf8']) {
854894
$container->getDefinition('routing.loader')->replaceArgument(2, ['utf8' => true]);
855895
}
@@ -901,6 +941,14 @@ private function registerSessionConfiguration(array $config, ContainerBuilder $c
901941
{
902942
$loader->load('session.xml');
903943

944+
$this->addClassesToPreload([
945+
'Symfony\Component\HttpFoundation\Session\SessionBagProxy',
946+
'Symfony\Component\HttpFoundation\Session\Storage\Handler\AbstractSessionHandler',
947+
'Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler',
948+
'Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy',
949+
'Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy',
950+
]);
951+
904952
// session storage
905953
$container->setAlias('session.storage', $config['storage_id'])->setPrivate(true);
906954
$options = ['cache_limiter' => '0'];
@@ -1118,6 +1166,10 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
11181166

11191167
$loader->load('translation.xml');
11201168

1169+
$this->addClassesToPreload([
1170+
'Symfony\Component\Translation\Formatter\IntlFormatter',
1171+
]);
1172+
11211173
// Use the "real" translator instead of the identity default
11221174
$container->setAlias('translator', 'translator.default')->setPublic(true);
11231175
$container->setAlias('translator.formatter', new Alias($config['formatter'], false));

‎src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,18 @@ public function load(array $configs, ContainerBuilder $container)
161161

162162
$container->registerForAutoconfiguration(VoterInterface::class)
163163
->addTag('security.voter');
164+
165+
$this->addClassesToPreload([
166+
'Symfony\Component\HttpFoundation\RequestMatcher',
167+
'Symfony\Component\Security\Core\Authorization\ExpressionLanguageProvider',
168+
'Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider',
169+
'Symfony\Component\Security\Core\Authentication\Token\AbstractToken',
170+
'Symfony\Component\Security\Core\Authentication\Token\AnonymousToken',
171+
'Symfony\Component\Security\Core\AuthenticationEvents',
172+
'Symfony\Component\Security\Core\Event\AuthenticationEvent',
173+
'Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent',
174+
'Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface',
175+
]);
164176
}
165177

166178
private function createRoleHierarchy(array $config, ContainerBuilder $container)

‎src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,18 @@ public function load(array $configs, ContainerBuilder $container)
170170
$container->removeDefinition('twig.cache_warmer');
171171
$container->removeDefinition('twig.template_cache_warmer');
172172
}
173+
174+
$this->addClassesToPreload([
175+
'Symfony\Component\Stopwatch\Section',
176+
'Twig\Cache\FilesystemCache',
177+
'Twig\Extension\CoreExtension',
178+
'Twig\Extension\EscaperExtension',
179+
'Twig\Extension\OptimizerExtension',
180+
'Twig\Extension\StagingExtension',
181+
'Twig\ExtensionSet',
182+
'Twig\Template',
183+
'Twig\TemplateWrapper',
184+
]);
173185
}
174186

175187
private function getBundleTemplatePaths(ContainerBuilder $container, array $config)

‎src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+67-14Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class PhpDumper extends Dumper
8080
private $inlinedRequires = [];
8181
private $circularReferences = [];
8282
private $singleUsePrivateIds = [];
83+
private $preload = [];
8384
private $addThrow = false;
8485
private $addGetService = false;
8586
private $locatedIds = [];
@@ -141,6 +142,7 @@ public function dump(array $options = [])
141142
'hot_path_tag' => 'container.hot_path',
142143
'inline_factories_parameter' => 'container.dumper.inline_factories',
143144
'inline_class_loader_parameter' => 'container.dumper.inline_class_loader',
145+
'preload_classes' => [],
144146
'service_locator_tag' => 'container.service_locator',
145147
'build_time' => time(),
146148
], $options);
@@ -225,8 +227,12 @@ public function dump(array $options = [])
225227

226228
$proxyClasses = $this->inlineFactories ? $this->generateProxyClasses() : null;
227229

230+
if ($options['preload_classes']) {
231+
$this->preload = array_combine($options['preload_classes'], $options['preload_classes']);
232+
}
233+
228234
$code =
229-
$this->startClass($options['class'], $baseClass, $preload).
235+
$this->startClass($options['class'], $baseClass).
230236
$this->addServices($services).
231237
$this->addDeprecatedAliases().
232238
$this->addDefaultParametersMethod()
@@ -301,7 +307,7 @@ public function dump(array $options = [])
301307
$id = hash('crc32', $hash.$time);
302308
$this->asFiles = false;
303309

304-
if ($preload && null !== $autoloadFile = $this->getAutoloadFile()) {
310+
if ($this->preload && null !== $autoloadFile = $this->getAutoloadFile()) {
305311
$autoloadFile = substr($this->export($autoloadFile), 2, -1);
306312

307313
$code[$options['class'].'.preload.php'] = <<<EOF
@@ -319,8 +325,10 @@ public function dump(array $options = [])
319325
320326
EOF;
321327

322-
foreach ($preload as $class) {
323-
$code[$options['class'].'.preload.php'] .= sprintf("\$classes[] = '%s';\n", $class);
328+
foreach ($this->preload as $class) {
329+
if ($class && (!(class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false)) || (new \ReflectionClass($class))->isUserDefined())) {
330+
$code[$options['class'].'.preload.php'] .= sprintf("\$classes[] = '%s';\n", $class);
331+
}
324332
}
325333

326334
$code[$options['class'].'.preload.php'] .= <<<'EOF'
@@ -366,6 +374,7 @@ public function dump(array $options = [])
366374
$this->circularReferences = [];
367375
$this->locatedIds = [];
368376
$this->exportedVariables = [];
377+
$this->preload = [];
369378

370379
$unusedEnvs = [];
371380
foreach ($this->container->getEnvCounters() as $env => $use) {
@@ -541,8 +550,13 @@ private function addServiceInclude(string $cId, Definition $definition): string
541550
if ($this->inlineRequires && (!$this->isHotPath($definition) || $this->getProxyDumper()->isProxyCandidate($definition))) {
542551
$lineage = [];
543552
foreach ($this->inlinedDefinitions as $def) {
544-
if (!$def->isDeprecated() && \is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass())) {
545-
$this->collectLineage($class, $lineage);
553+
if (!$def->isDeprecated()) {
554+
if ($class = $this->getFactoryClass($def)) {
555+
$this->collectLineage($class, $lineage);
556+
}
557+
if ($class = $def->getClass()) {
558+
$this->collectLineage($class, $lineage);
559+
}
546560
}
547561
}
548562

@@ -551,9 +565,13 @@ private function addServiceInclude(string $cId, Definition $definition): string
551565
&& ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior
552566
&& $this->container->has($id)
553567
&& $this->isTrivialInstance($def = $this->container->findDefinition($id))
554-
&& \is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass())
555568
) {
556-
$this->collectLineage($class, $lineage);
569+
if ($class = $this->getFactoryClass($def)) {
570+
$this->collectLineage($class, $lineage);
571+
}
572+
if ($class = $def->getClass()) {
573+
$this->collectLineage($class, $lineage);
574+
}
557575
}
558576
}
559577

@@ -798,6 +816,15 @@ protected function {$methodName}($lazyInitialization)
798816

799817
if ($definition->isDeprecated()) {
800818
$code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id)));
819+
} else {
820+
foreach ($this->inlinedDefinitions as $def) {
821+
if ($class = $this->getFactoryClass($def)) {
822+
$this->preload[$class] = $class;
823+
}
824+
if ($class = ltrim($def->getClass(), '\\')) {
825+
$this->preload[$class] = $class;
826+
}
827+
}
801828
}
802829

803830
if ($this->getProxyDumper()->isProxyCandidate($definition)) {
@@ -953,7 +980,18 @@ private function addServices(array &$services = null): string
953980
$definitions = $this->container->getDefinitions();
954981
ksort($definitions);
955982
foreach ($definitions as $id => $definition) {
956-
$services[$id] = $definition->isSynthetic() ? null : $this->addService($id, $definition);
983+
if (!$definition->isSynthetic()) {
984+
$services[$id] = $this->addService($id, $definition);
985+
} else {
986+
$services[$id] = null;
987+
988+
if ($class = $this->getFactoryClass($definition)) {
989+
$this->preload[$class] = $class;
990+
}
991+
if ($class = ltrim($definition->getClass(), '\\')) {
992+
$this->preload[$class] = $class;
993+
}
994+
}
957995
}
958996

959997
foreach ($definitions as $id => $definition) {
@@ -1054,7 +1092,7 @@ private function addNewInstance(Definition $definition, string $return = '', str
10541092
return $return.sprintf('new %s(%s)', $this->dumpLiteralClass($this->dumpValue($class)), implode(', ', $arguments)).$tail;
10551093
}
10561094

1057-
private function startClass(string $class, string $baseClass, ?array &$preload): string
1095+
private function startClass(string $class, string $baseClass): string
10581096
{
10591097
$namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : '';
10601098

@@ -1117,7 +1155,7 @@ public function __construct()
11171155
$code .= $this->addMethodMap();
11181156
$code .= $this->asFiles && !$this->inlineFactories ? $this->addFileMap() : '';
11191157
$code .= $this->addAliases();
1120-
$code .= $this->addInlineRequires($preload);
1158+
$code .= $this->addInlineRequires();
11211159
$code .= <<<EOF
11221160
}
11231161
@@ -1317,7 +1355,7 @@ protected function {$methodNameAlias}()
13171355
return $code;
13181356
}
13191357

1320-
private function addInlineRequires(?array &$preload): string
1358+
private function addInlineRequires(): string
13211359
{
13221360
if (!$this->hotPathTag || !$this->inlineRequires) {
13231361
return '';
@@ -1335,8 +1373,10 @@ private function addInlineRequires(?array &$preload): string
13351373
$inlinedDefinitions = $this->getDefinitionsFromArguments([$definition]);
13361374

13371375
foreach ($inlinedDefinitions as $def) {
1338-
if (\is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass())) {
1339-
$preload[$class] = $class;
1376+
if ($class = $this->getFactoryClass($def)) {
1377+
$this->collectLineage($class, $lineage);
1378+
}
1379+
if ($class = $def->getClass()) {
13401380
$this->collectLineage($class, $lineage);
13411381
}
13421382
}
@@ -2058,4 +2098,17 @@ private function getAutoloadFile(): ?string
20582098

20592099
return null;
20602100
}
2101+
2102+
private function getFactoryClass(Definition $definition): ?string
2103+
{
2104+
while ($definition instanceof Definition && \is_array($factory = $definition->getFactory())) {
2105+
if (\is_string($factory[0])) {
2106+
return ltrim($factory[0], '\\');
2107+
}
2108+
2109+
$definition = $factory[0];
2110+
}
2111+
2112+
return null;
2113+
}
20612114
}

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,24 @@ class ProjectServiceContainer extends Container
531531
}
532532
}
533533

534+
[ProjectServiceContainer.preload.php] => <?php
535+
%A
536+
537+
$classes = [];
538+
$classes[] = 'Bar\FooClass';
539+
$classes[] = 'Baz';
540+
$classes[] = 'ConfClass';
541+
$classes[] = 'Bar';
542+
$classes[] = 'BazClass';
543+
$classes[] = 'Foo';
544+
$classes[] = 'LazyContext';
545+
$classes[] = 'FooBarBaz';
546+
$classes[] = 'FactoryClass';
547+
$classes[] = 'Request';
548+
$classes[] = 'Symfony\Component\DependencyInjection\ContainerInterface';
549+
550+
%A
551+
534552
[ProjectServiceContainer.php] => <?php
535553

536554
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_inlined_factories.txt

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_inlined_factories.txt
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,16 @@ class ProjectServiceContainer extends Container
536536

537537
$classes = [];
538538
$classes[] = 'Bar\FooClass';
539+
$classes[] = 'Baz';
540+
$classes[] = 'ConfClass';
541+
$classes[] = 'Bar';
542+
$classes[] = 'BazClass';
543+
$classes[] = 'Foo';
544+
$classes[] = 'LazyContext';
545+
$classes[] = 'FooBarBaz';
546+
$classes[] = 'FactoryClass';
547+
$classes[] = 'Request';
548+
$classes[] = 'Symfony\Component\DependencyInjection\ContainerInterface';
539549

540550
%A
541551

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_lazy_inlined_factories.txt

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_lazy_inlined_factories.txt
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,16 @@ class FooClass_%s extends \Bar\FooClass implements \ProxyManager\Proxy\VirtualPr
165165
%A
166166
}
167167

168+
[ProjectServiceContainer.preload.php] => <?php
169+
%A
170+
171+
$classes = [];
172+
$classes[] = 'Bar\FooClass';
173+
$classes[] = 'Bar\FooLazyClass';
174+
$classes[] = 'Symfony\Component\DependencyInjection\ContainerInterface';
175+
176+
%A
177+
168178
[ProjectServiceContainer.php] => <?php
169179

170180
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_non_shared_lazy_as_files.txt

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_non_shared_lazy_as_files.txt
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ class ProjectServiceContainer extends Container
8383
}
8484
}
8585

86+
[ProjectServiceContainer.preload.php] => <?php
87+
%A
88+
89+
$classes = [];
90+
$classes[] = 'Bar\FooLazyClass';
91+
$classes[] = 'Symfony\Component\DependencyInjection\ContainerInterface';
92+
93+
%A
94+
8695
[ProjectServiceContainer.php] => <?php
8796

8897
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.