Skip to content

Commit 97b31fc

Browse files
feature #60597 [DependencyInjection][FrameworkBundle] Use php-serialize to dump the container for debug/lint commands (nicolas-grekas)
This PR was merged into the 7.4 branch. Discussion ---------- [DependencyInjection][FrameworkBundle] Use php-serialize to dump the container for debug/lint commands | Q | A | ------------- | --- | Branch? | 7.4 | Bug fix? | no | New feature? | no | Deprecations? | no | Issues | - | License | MIT To unlock #60568 this uses `serialize()` to dump the container, next to the XML dump. Commits ------- c128f55b842 [DependencyInjection][FrameworkBundle] Use php-serialize to dump the container for debug/lint commands
2 parents 890f753 + 0ecd228 commit 97b31fc

File tree

3 files changed

+59
-15
lines changed

3 files changed

+59
-15
lines changed

Command/BuildDebugContainerTrait.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ protected function getContainerBuilder(KernelInterface $kernel): ContainerBuilde
3939
return $this->container;
4040
}
4141

42-
if (!$kernel->isDebug() || !$kernel->getContainer()->getParameter('debug.container.dump') || !(new ConfigCache($kernel->getContainer()->getParameter('debug.container.dump'), true))->isFresh()) {
42+
$file = $kernel->isDebug() ? $kernel->getContainer()->getParameter('debug.container.dump') : false;
43+
44+
if (!$file || !(new ConfigCache($file, true))->isFresh()) {
4345
$buildContainer = \Closure::bind(function () {
4446
$this->initializeBundles();
4547

@@ -57,13 +59,17 @@ protected function getContainerBuilder(KernelInterface $kernel): ContainerBuilde
5759
return $containerBuilder;
5860
}, $kernel, $kernel::class);
5961
$container = $buildContainer();
60-
(new XmlFileLoader($container, new FileLocator()))->load($kernel->getContainer()->getParameter('debug.container.dump'));
61-
$locatorPass = new ServiceLocatorTagPass();
62-
$locatorPass->process($container);
6362

64-
$container->getCompilerPassConfig()->setBeforeOptimizationPasses([]);
65-
$container->getCompilerPassConfig()->setOptimizationPasses([]);
66-
$container->getCompilerPassConfig()->setBeforeRemovingPasses([]);
63+
if (str_ends_with($file, '.xml') && is_file(substr_replace($file, '.ser', -4))) {
64+
$dumpedContainer = unserialize(file_get_contents(substr_replace($file, '.ser', -4)));
65+
$container->setDefinitions($dumpedContainer->getDefinitions());
66+
$container->setAliases($dumpedContainer->getAliases());
67+
$container->__construct($dumpedContainer->getParameterBag());
68+
} else {
69+
(new XmlFileLoader($container, new FileLocator()))->load($file);
70+
$locatorPass = new ServiceLocatorTagPass();
71+
$locatorPass->process($container);
72+
}
6773
}
6874

6975
return $this->container = $container;

Command/ContainerLintCommand.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,10 @@ private function getContainerBuilder(): ContainerBuilder
7979
}
8080

8181
$kernel = $this->getApplication()->getKernel();
82-
$kernelContainer = $kernel->getContainer();
82+
$container = $kernel->getContainer();
83+
$file = $container->isDebug() ? $container->getParameter('debug.container.dump') : false;
8384

84-
if (!$kernel->isDebug() || !$kernelContainer->getParameter('debug.container.dump') || !(new ConfigCache($kernelContainer->getParameter('debug.container.dump'), true))->isFresh()) {
85+
if (!$file || !(new ConfigCache($file, true))->isFresh()) {
8586
if (!$kernel instanceof Kernel) {
8687
throw new RuntimeException(\sprintf('This command does not support the application kernel: "%s" does not extend "%s".', get_debug_type($kernel), Kernel::class));
8788
}
@@ -93,12 +94,17 @@ private function getContainerBuilder(): ContainerBuilder
9394
}, $kernel, $kernel::class);
9495
$container = $buildContainer();
9596
} else {
96-
if (!$kernelContainer instanceof Container) {
97-
throw new RuntimeException(\sprintf('This command does not support the application container: "%s" does not extend "%s".', get_debug_type($kernelContainer), Container::class));
97+
if (str_ends_with($file, '.xml') && is_file(substr_replace($file, '.ser', -4))) {
98+
$container = unserialize(file_get_contents(substr_replace($file, '.ser', -4)));
99+
} else {
100+
(new XmlFileLoader($container = new ContainerBuilder(new EnvPlaceholderParameterBag()), new FileLocator()))->load($file);
98101
}
99102

100-
(new XmlFileLoader($container = new ContainerBuilder($parameterBag = new EnvPlaceholderParameterBag()), new FileLocator()))->load($kernelContainer->getParameter('debug.container.dump'));
103+
if (!$container instanceof ContainerBuilder) {
104+
throw new RuntimeException(\sprintf('This command does not support the application container: "%s" is not a "%s".', get_debug_type($container), ContainerBuilder::class));
105+
}
101106

107+
$parameterBag = $container->getParameterBag();
102108
$refl = new \ReflectionProperty($parameterBag, 'resolved');
103109
$refl->setValue($parameterBag, true);
104110

DependencyInjection/Compiler/ContainerBuilderDebugDumpPass.php

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313

1414
use Symfony\Component\Config\ConfigCache;
1515
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16+
use Symfony\Component\DependencyInjection\Compiler\ResolveEnvPlaceholdersPass;
1617
use Symfony\Component\DependencyInjection\ContainerBuilder;
1718
use Symfony\Component\DependencyInjection\Dumper\XmlDumper;
19+
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
20+
use Symfony\Component\Filesystem\Filesystem;
1821

1922
/**
2023
* Dumps the ContainerBuilder to a cache file so that it can be used by
@@ -31,9 +34,38 @@ public function process(ContainerBuilder $container): void
3134
return;
3235
}
3336

34-
$cache = new ConfigCache($container->getParameter('debug.container.dump'), true);
35-
if (!$cache->isFresh()) {
36-
$cache->write((new XmlDumper($container))->dump(), $container->getResources());
37+
$file = $container->getParameter('debug.container.dump');
38+
$cache = new ConfigCache($file, true);
39+
if ($cache->isFresh()) {
40+
return;
41+
}
42+
$cache->write((new XmlDumper($container))->dump(), $container->getResources());
43+
44+
if (!str_ends_with($file, '.xml')) {
45+
return;
46+
}
47+
48+
$file = substr_replace($file, '.ser', -4);
49+
50+
try {
51+
$dump = new ContainerBuilder(clone $container->getParameterBag());
52+
$dump->setDefinitions(unserialize(serialize($container->getDefinitions())));
53+
$dump->setAliases($container->getAliases());
54+
55+
if (($bag = $container->getParameterBag()) instanceof EnvPlaceholderParameterBag) {
56+
(new ResolveEnvPlaceholdersPass(null))->process($dump);
57+
$dump->__construct(new EnvPlaceholderParameterBag($container->resolveEnvPlaceholders($bag->all())));
58+
}
59+
60+
$fs = new Filesystem();
61+
$fs->dumpFile($file, serialize($dump));
62+
$fs->chmod($file, 0666, umask());
63+
} catch (\Throwable $e) {
64+
$container->getCompiler()->log($this, $e->getMessage());
65+
// ignore serialization and file-system errors
66+
if (file_exists($file)) {
67+
@unlink($file);
68+
}
3769
}
3870
}
3971
}

0 commit comments

Comments
 (0)