Skip to content

Commit 256e765

Browse files
[DI] Allow dumping the container in one file instead of many files
1 parent 52e9fb9 commit 256e765

File tree

2 files changed

+65
-23
lines changed

2 files changed

+65
-23
lines changed

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
4.4.0
55
-----
66

7+
* added support for dumping the container in one file instead of many files
78
* deprecated support for short factories and short configurators in Yaml
89
* deprecated `tagged` in favor of `tagged_iterator`
910
* deprecated passing an instance of `Symfony\Component\DependencyInjection\Parameter` as class name to `Symfony\Component\DependencyInjection\Definition`

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

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class PhpDumper extends Dumper
7272
private $namespace;
7373
private $asFiles;
7474
private $hotPathTag;
75+
private $inlineFactories;
7576
private $inlineRequires;
7677
private $inlinedRequires = [];
7778
private $circularReferences = [];
@@ -134,6 +135,7 @@ public function dump(array $options = [])
134135
'as_files' => false,
135136
'debug' => true,
136137
'hot_path_tag' => 'container.hot_path',
138+
'inline_factories_parameter' => 'container.dumper.inline_factories',
137139
'inline_class_loader_parameter' => 'container.dumper.inline_class_loader',
138140
'service_locator_tag' => 'container.service_locator',
139141
'build_time' => time(),
@@ -143,6 +145,7 @@ public function dump(array $options = [])
143145
$this->namespace = $options['namespace'];
144146
$this->asFiles = $options['as_files'];
145147
$this->hotPathTag = $options['hot_path_tag'];
148+
$this->inlineFactories = $this->asFiles && $options['inline_factories_parameter'] && $this->container->hasParameter($options['inline_factories_parameter']) && $this->container->getParameter($options['inline_factories_parameter']);
146149
$this->inlineRequires = $options['inline_class_loader_parameter'] && $this->container->hasParameter($options['inline_class_loader_parameter']) && $this->container->getParameter($options['inline_class_loader_parameter']);
147150
$this->serviceLocatorTag = $options['service_locator_tag'];
148151

@@ -215,6 +218,8 @@ public function dump(array $options = [])
215218
}
216219
}
217220

221+
$proxyClasses = $this->generateProxyClasses();
222+
218223
$code =
219224
$this->startClass($options['class'], $baseClass, $baseClassWithNamespace).
220225
$this->addServices($services).
@@ -258,13 +263,24 @@ public function dump(array $options = [])
258263
$files['removed-ids.php'] = $c .= "];\n";
259264
}
260265

261-
foreach ($this->generateServiceFiles($services) as $file => $c) {
262-
$files[$file] = $fileStart.$c;
266+
if (!$this->inlineFactories) {
267+
foreach ($this->generateServiceFiles($services) as $file => $c) {
268+
$files[$file] = $fileStart.$c;
269+
}
270+
foreach ($proxyClasses as $file => $c) {
271+
$files[$file] = "<?php\n".$c;
272+
}
263273
}
264-
foreach ($this->generateProxyClasses() as $file => $c) {
265-
$files[$file] = "<?php\n".$c;
274+
275+
$code .= $this->endClass();
276+
277+
if ($this->inlineFactories) {
278+
foreach ($proxyClasses as $c) {
279+
$code .= $c;
280+
}
266281
}
267-
$files[$options['class'].'.php'] = $code.$this->endClass();
282+
283+
$files[$options['class'].'.php'] = $code;
268284
$hash = ucfirst(strtr(ContainerBuilder::hash($files), '._', 'xx'));
269285
$code = [];
270286

@@ -303,7 +319,7 @@ public function dump(array $options = [])
303319
EOF;
304320
} else {
305321
$code .= $this->endClass();
306-
foreach ($this->generateProxyClasses() as $c) {
322+
foreach ($proxyClasses as $c) {
307323
$code .= $c;
308324
}
309325
}
@@ -422,8 +438,9 @@ private function collectLineage($class, array &$lineage)
422438
$lineage[$class] = substr($exportedFile, 1, -1);
423439
}
424440

425-
private function generateProxyClasses()
441+
private function generateProxyClasses(): array
426442
{
443+
$proxyClasses = [];
427444
$alreadyGenerated = [];
428445
$definitions = $this->container->getDefinitions();
429446
$strip = '' === $this->docStar && method_exists('Symfony\Component\HttpKernel\Kernel', 'stripComments');
@@ -442,19 +459,39 @@ private function generateProxyClasses()
442459
if ("\n" === $proxyCode = "\n".$proxyDumper->getProxyCode($definition)) {
443460
continue;
444461
}
462+
463+
if ($this->inlineRequires) {
464+
$lineage = [];
465+
$this->collectLineage($class, $lineage);
466+
467+
$code = '';
468+
foreach (array_diff_key(array_flip($lineage), $this->inlinedRequires) as $file => $class) {
469+
if ($this->inlineFactories) {
470+
$this->inlinedRequires[$file] = true;
471+
}
472+
$file = preg_replace('#^\\$this->targetDirs\[(\d++)\]#', sprintf('\dirname(__DIR__, %d + $1)', $this->asFiles), $file);
473+
$code .= sprintf("include_once %s;\n", $file);
474+
}
475+
476+
$proxyCode = $code.$proxyCode;
477+
}
478+
445479
if ($strip) {
446480
$proxyCode = "<?php\n".$proxyCode;
447481
$proxyCode = substr(Kernel::stripComments($proxyCode), 5);
448482
}
449-
yield sprintf('%s.php', explode(' ', $proxyCode, 3)[1]) => $proxyCode;
483+
484+
$proxyClasses[sprintf('%s.php', explode(' ', $proxyCode, 3)[1])] = $proxyCode;
450485
}
486+
487+
return $proxyClasses;
451488
}
452489

453490
private function addServiceInclude(string $cId, Definition $definition): string
454491
{
455492
$code = '';
456493

457-
if ($this->inlineRequires && !$this->isHotPath($definition)) {
494+
if ($this->inlineRequires && (!$this->isHotPath($definition) || $this->getProxyDumper()->isProxyCandidate($definition))) {
458495
$lineage = [];
459496
foreach ($this->inlinedDefinitions as $def) {
460497
if (!$def->isDeprecated() && \is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass())) {
@@ -685,7 +722,7 @@ private function addService(string $id, Definition $definition): array
685722
$lazyInitialization = '';
686723
}
687724

688-
$asFile = $this->asFiles && !$this->isHotPath($definition);
725+
$asFile = $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition);
689726
$methodName = $this->generateMethodName($id);
690727
if ($asFile) {
691728
$file = $methodName.'.php';
@@ -711,17 +748,16 @@ protected function {$methodName}($lazyInitialization)
711748
$this->serviceCalls = [];
712749
$this->inlinedDefinitions = $this->getDefinitionsFromArguments([$definition], null, $this->serviceCalls);
713750

714-
$code .= $this->addServiceInclude($id, $definition);
751+
if ($definition->isDeprecated()) {
752+
$code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id)));
753+
}
715754

716755
if ($this->getProxyDumper()->isProxyCandidate($definition)) {
717756
$factoryCode = $asFile ? ($definition->isShared() ? "\$this->load('%s.php', false)" : '$this->factories[%2$s](false)') : '$this->%s(false)';
718757
$code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName, $this->doExport($id)));
719758
}
720759

721-
if ($definition->isDeprecated()) {
722-
$code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id)));
723-
}
724-
760+
$code .= $this->addServiceInclude($id, $definition);
725761
$code .= $this->addInlineService($id, $definition);
726762

727763
if ($asFile) {
@@ -1024,7 +1060,7 @@ public function __construct()
10241060

10251061
$code .= $this->addSyntheticIds();
10261062
$code .= $this->addMethodMap();
1027-
$code .= $this->asFiles ? $this->addFileMap() : '';
1063+
$code .= $this->asFiles && !$this->inlineFactories ? $this->addFileMap() : '';
10281064
$code .= $this->addAliases();
10291065
$code .= $this->addInlineRequires();
10301066
$code .= <<<EOF
@@ -1043,7 +1079,7 @@ public function isCompiled()
10431079
EOF;
10441080
$code .= $this->addRemovedIds();
10451081

1046-
if ($this->asFiles) {
1082+
if ($this->asFiles && !$this->inlineFactories) {
10471083
$code .= <<<EOF
10481084
10491085
protected function load(\$file, \$lazyLoad = true)
@@ -1059,10 +1095,10 @@ protected function load(\$file, \$lazyLoad = true)
10591095
if (!$proxyDumper->isProxyCandidate($definition)) {
10601096
continue;
10611097
}
1062-
if ($this->asFiles) {
1098+
if ($this->asFiles && !$this->inlineFactories) {
10631099
$proxyLoader = '$this->load("{$class}.php")';
1064-
} elseif ($this->namespace) {
1065-
$proxyLoader = 'class_alias("'.$this->namespace.'\\\\{$class}", $class, false)';
1100+
} elseif ($this->namespace || $this->inlineFactories) {
1101+
$proxyLoader = 'class_alias(__NAMESPACE__."\\\\$class", $class, false)';
10661102
} else {
10671103
$proxyLoader = '';
10681104
}
@@ -1140,7 +1176,7 @@ private function addMethodMap(): string
11401176
$definitions = $this->container->getDefinitions();
11411177
ksort($definitions);
11421178
foreach ($definitions as $id => $definition) {
1143-
if (!$definition->isSynthetic() && $definition->isPublic() && (!$this->asFiles || $this->isHotPath($definition))) {
1179+
if (!$definition->isSynthetic() && $definition->isPublic() && (!$this->asFiles || $this->inlineFactories || $this->isHotPath($definition))) {
11441180
$code .= ' '.$this->doExport($id).' => '.$this->doExport($this->generateMethodName($id)).",\n";
11451181
}
11461182
}
@@ -1237,6 +1273,11 @@ private function addInlineRequires(): string
12371273

12381274
foreach ($this->container->findTaggedServiceIds($this->hotPathTag) as $id => $tags) {
12391275
$definition = $this->container->getDefinition($id);
1276+
1277+
if ($this->getProxyDumper()->isProxyCandidate($definition)) {
1278+
continue;
1279+
}
1280+
12401281
$inlinedDefinitions = $this->getDefinitionsFromArguments([$definition]);
12411282

12421283
foreach ($inlinedDefinitions as $def) {
@@ -1578,7 +1619,7 @@ private function dumpValue($value, bool $interpolate = true): string
15781619
continue;
15791620
}
15801621
$definition = $this->container->findDefinition($id = (string) $v);
1581-
$load = !($definition->hasErrors() && $e = $definition->getErrors()) ? $this->asFiles && !$this->isHotPath($definition) : reset($e);
1622+
$load = !($definition->hasErrors() && $e = $definition->getErrors()) ? $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition) : reset($e);
15821623
$serviceMap .= sprintf("\n %s => [%s, %s, %s, %s],",
15831624
$this->export($k),
15841625
$this->export($definition->isShared() ? ($definition->isPublic() ? 'services' : 'privates') : false),
@@ -1716,7 +1757,7 @@ private function getServiceCall(string $id, Reference $reference = null): string
17161757
$code = sprintf('$this->%s[%s] = %s', $definition->isPublic() ? 'services' : 'privates', $this->doExport($id), $code);
17171758
}
17181759
$code = "($code)";
1719-
} elseif ($this->asFiles && !$this->isHotPath($definition)) {
1760+
} elseif ($this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition)) {
17201761
$code = sprintf("\$this->load('%s.php')", $this->generateMethodName($id));
17211762
if (!$definition->isShared()) {
17221763
$factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id));

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy