8000 [DI] Fix initialization of legacy containers by delaying include_once · symfony/symfony@5a8b3a7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5a8b3a7

Browse files
[DI] Fix initialization of legacy containers by delaying include_once
1 parent d2a316f commit 5a8b3a7

File tree

4 files changed

+79
-58
lines changed

4 files changed

+79
-58
lines changed

src/Symfony/Component/DependencyInjection/Container.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ public function setParameter($name, $value)
167167
*/
168168
public function set($id, $service)
169169
{
170+
// Runs the internal initializer; used by the dumped container to include always-needed files
171+
if (isset($this->privates["\0"]) && $this->privates["\0"] instanceof \Closure) {
172+
$initialize = $this->privates["\0"];
173+
unset($this->privates["\0"]);
174+
$initialize();
175+
}
176+
170177
$id = $this->normalizeId($id);
171178

172179
if ('service_container' === $id) {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,16 +1243,16 @@ private function addInlineRequires()
12431243
}
12441244
}
12451245

1246-
$code = "\n";
1246+
$code = '';
12471247

12481248
foreach ($lineage as $file) {
12491249
if (!isset($this->inlinedRequires[$file])) {
12501250
$this->inlinedRequires[$file] = true;
1251-
$code .= sprintf(" include_once %s;\n", $file);
1251+
$code .= sprintf("\n include_once %s;", $file);
12521252
}
12531253
}
12541254

1255-
return "\n" === $code ? '' : $code;
1255+
return $code ? sprintf("\n \$this->privates[\"\\0\"] = function () {%s\n };\n", $code) : '';
12561256
}
12571257

12581258
/**

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_requires.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,12 @@ public function __construct()
4646

4747
$this->aliases = array();
4848

49-
include_once $this->targetDirs[1].'/includes/HotPath/I1.php';
50-
include_once $this->targetDirs[1].'/includes/HotPath/P1.php';
51-
include_once $this->targetDirs[1].'/includes/HotPath/T1.php';
52-
include_once $this->targetDirs[1].'/includes/HotPath/C1.php';
49+
$this->privates["\0"] = function () {
50+
include_once $this->targetDirs[1].'/includes/HotPath/I1.php';
51+
include_once $this->targetDirs[1].'/includes/HotPath/P1.php';
52+
include_once $this->targetDirs[1].'/includes/HotPath/T1.php';
53+
include_once $this->targetDirs[1].'/includes/HotPath/C1.php';
54+
};
5355
}
5456

5557
public function getRemovedIds()

src/Symfony/Component/HttpKernel/Kernel.php

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -581,80 +581,92 @@ protected function initializeContainer()
581581
$class = $this->getContainerClass();
582582
$cacheDir = $this->warmupDir ?: $this->getCacheDir();
583583
$cache = new ConfigCache($cacheDir.'/'.$class.'.php', $this->debug);
584+
$oldContainer = null;
584585
if ($fresh = $cache->isFresh()) {
585586
// Silence E_WARNING to ignore "include" failures - don't use "@" to prevent silencing fatal errors
586587
$errorLevel = error_reporting(\E_ALL ^ \E_WARNING);
588+
$fresh = $oldContainer = false;
587589
try {
588590
$this->container = include $cache->getPath();
591+
if (\is_object($this->container)) {
592+
$this->container->set('kernel', $this);
593+
$oldContainer = $this->container;
594+
$fresh = true;
595+
}
596+
} catch (\Throwable $e) {
597+
} catch (\Exception $e) {
589598
} finally {
590599
error_reporting($errorLevel);
591600
}
592-
$fresh = \is_object($this->container);
593601
}
594-
if (!$fresh) {
595-
if ($this->debug) {
596-
$collectedLogs = array();
597-
$previousHandler = defined('PHPUNIT_COMPOSER_INSTALL');
598-
$previousHandler = $previousHandler ?: set_error_handler(function ($type, $message, $file, $line) use (&$collectedLogs, &$previousHandler) {
599-
if (E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) {
600-
return $previousHandler ? $previousHandler($type & ~E_WARNING, $message, $file, $line) : E_WARNING === $type;
601-
}
602602

603-
if (isset($collectedLogs[$message])) {
604-
++$collectedLogs[$message]['count'];
603+
if ($fresh) {
604+
return;
605+
}
605606

606-
return;
607-
}
607+
if ($this->debug) {
608+
$collectedLogs = array();
609+
$previousHandler = defined('PHPUNIT_COMPOSER_INSTALL');
610+
$previousHandler = $previousHandler ?: set_error_handler(function ($type, $message, $file, $line) use (&$collectedLogs, &$previousHandler) {
611+
if (E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) {
612+
return $previousHandler ? $previousHandler($type, $message, $file, $line) : false;
613+
}
614+
615+
if (isset($collectedLogs[$message])) {
616+
++$collectedLogs[$message]['count'];
617+
618+
return;
619+
}
608620

609-
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
610-
// Clean the trace by removing first frames added by the error handler itself.
611-
for ($i = 0; isset($backtrace[$i]); ++$i) {
612-
if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {
613-
$backtrace = array_slice($backtrace, 1 + $i);
614-
break;
615-
}
621+
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
622+
// Clean the trace by removing first frames added by the error handler itself.
623+
for ($i = 0; isset($backtrace[$i]); ++$i) {
624+
if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {
625+
$backtrace = array_slice($backtrace, 1 + $i);
626+
break;
616627
}
628+
}
617629

618-
$collectedLogs[$message] = array(
619-
'type' => $type,
620-
'message' => $message,
621-
'file' => $file,
622-
'line' => $line,
623-
'trace' => $backtrace,
624-
'count' => 1,
625-
);
626-
});
627-
} else {
628-
$errorLevel = error_reporting(\E_ALL ^ \E_WARNING);
630+
$collectedLogs[$message] = array(
631+
'type' => $type,
632+
'message' => $message,
633+
'file' => $file,
634+
'line' => $line,
635+
'trace' => $backtrace,
636+
'count' => 1,
637+
);
638+
});
639+
}
640+
641+
try {
642+
$container = null;
643+
$container = $this->buildContainer();
644+
$container->compile();
645+
} finally {
646+
if ($this->debug && true !== $previousHandler) {
647+
restore_error_handler();
648+
649+
file_put_contents($cacheDir.'/'.$class.'Deprecations.log', serialize(array_values($collectedLogs)));
650+
file_put_contents($cacheDir.'/'.$class.'Compiler.log', null !== $container ? implode("\n", $container->getCompiler()->getLog()) : '');
629651
}
652+
}
630653

654+
if (null === $oldContainer) {
655+
$errorLevel = error_reporting(\E_ALL ^ \E_WARNING);
631656
try {
632-
$container = null;
633-
$container = $this->buildContainer();
634-
$container->compile();
635-
636-
$oldContainer = file_exists($cache->getPath()) && is_object($oldContainer = include $cache->getPath()) ? new \ReflectionClass($oldContainer) : false;
657+
$oldContainer = include $cache->getPath();
658+
} catch (\Throwable $e) {
659+
} catch (\Exception $e) {
637660
} finally {
638-
if (!$this->debug) {
639-
error_reporting($errorLevel);
640-
} elseif (true !== $previousHandler) {
641-
restore_error_handler();
642-
643-
file_put_contents($cacheDir.'/'.$class.'Deprecations.log', serialize(array_values($collectedLogs)));
644-
file_put_contents($cacheDir.'/'.$class.'Compiler.log', null !== $container ? implode("\n", $container->getCompiler()->getLog()) : '');
645-
}
661+
error_reporting($errorLevel);
646662
}
647-
648-
$this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass());
649-
$this->container = require $cache->getPath();
650663
}
664+
$oldContainer = is_object($oldContainer) ? new \ReflectionClass($oldContainer) : false;
651665

666+
$this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass());
667+
$this->container = require $cache->getPath();
652668
$this->container->set('kernel', $this);
653669

654-
if ($fresh) {
655-
return;
656-
}
657-
658670
if ($oldContainer && get_class($this->container) !== $oldContainer->name) {
659671
// Because concurrent requests might still be using them,
660672
// old container files are not removed immediately,

0 commit comments

Comments
 (0)
0