Skip to content

Commit e2b7dce

Browse files
[DI] generate preload.php file for PHP 7.4 in cache folder
1 parent 567cb27 commit e2b7dce

File tree

2 files changed

+63
-20
lines changed

2 files changed

+63
-20
lines changed

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

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;
3333
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper;
3434
use Symfony\Component\DependencyInjection\Parameter;
35+
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
3536
use Symfony\Component\DependencyInjection\Reference;
3637
use Symfony\Component\DependencyInjection\ServiceLocator as BaseServiceLocator;
3738
use Symfony\Component\DependencyInjection\TypedReference;
@@ -216,7 +217,7 @@ public function dump(array $options = [])
216217
}
217218

218219
$code =
219-
$this->startClass($options['class'], $baseClass, $baseClassWithNamespace).
220+
$this->startClass($options['class'], $baseClass, $baseClassWithNamespace, $preload).
220221
$this->addServices($services).
221222
$this->addDeprecatedAliases().
222223
$this->addDefaultParametersMethod()
@@ -243,6 +244,10 @@ public function dump(array $options = [])
243244
EOF;
244245
$files = [];
245246

247+
if ($preload) {
248+
$files['preload.php'] = "<?php\n".str_replace("\n include_once ", "\ninclude_once ", $preload)."\n";
249+
}
250+
246251
$ids = $this->container->getRemovedIds();
247252
foreach ($this->container->getDefinitions() as $id => $definition) {
248253
if (!$definition->isPublic()) {
@@ -277,6 +282,39 @@ public function dump(array $options = [])
277282
$time = $options['build_time'];
278283
$id = hash('crc32', $hash.$time);
279284

285+
if ($preload) {
286+
$preload = <<<EOF
287+
<?php
288+
289+
// This file has been auto-generated by the Symfony Dependency Injection Component
290+
// You can reference it in the "opcache.preload" php.ini setting on PHP >= 7.4 when preloading is desired
291+
292+
293+
EOF;
294+
295+
$lineage = [];
296+
297+
$this->collectLineage($baseClassWithNamespace, $lineage, true);
298+
$lineage[] = "__DIR__.'/Container{$hash}/{$options['class']}.php'";
299+
$lineage[] = "__DIR__.'/Container{$hash}/preload.php'";
300+
301+
foreach ($lineage as $file) {
302+
$this->inlinedRequires[$file] = true;
303+
$preload .= sprintf("include_once %s;\n", preg_replace('#^\\$this->targetDirs\[(\d++)\]#', 'dirname(__DIR__, $1)', $file));
304+
}
305+
306+
$this->collectLineage(EnvPlaceholderParameterBag::class, $lineage);
307+
308+
foreach ($lineage as $file) {
309+
if (!isset($this->inlinedRequires[$file])) {
310+
$this->inlinedRequires[$file] = true;
311+
$preload .= sprintf("include_once %s;\n", preg_replace('#^\\$this->targetDirs\[(\d++)\]#', 'dirname(__DIR__, $1)', $file));
312+
}
313+
}
314+
315+
$code[$options['class'].'.preload.php'] = $preload;
316+
}
317+
280318
$code[$options['class'].'.php'] = <<<EOF
281319
<?php
282320
{$namespaceLine}
@@ -391,15 +429,15 @@ private function connectCircularReferences($sourceId, &$currentPath, &$subPath =
391429
unset($subPath[$sourceId]);
392430
}
393431

394-
private function collectLineage($class, array &$lineage)
432+
private function collectLineage($class, array &$lineage, bool $allowContainer = false)
395433
{
396434
if (isset($lineage[$class])) {
397435
return;
398436
}
399437
if (!$r = $this->container->getReflectionClass($class, false)) {
400438
return;
401439
}
402-
if ($this->container instanceof $class) {
440+
if (!$allowContainer && $this->container instanceof $class) {
403441
return;
404442
}
405443
$file = $r->getFileName();
@@ -408,15 +446,15 @@ private function collectLineage($class, array &$lineage)
408446
}
409447

410448
if ($parent = $r->getParentClass()) {
411-
$this->collectLineage($parent->name, $lineage);
449+
$this->collectLineage($parent->name, $lineage, $allowContainer);
412450
}
413451

414452
foreach ($r->getInterfaces() as $parent) {
415-
$this->collectLineage($parent->name, $lineage);
453+
$this->collectLineage($parent->name, $lineage, $allowContainer);
416454
}
417455

418456
foreach ($r->getTraits() as $parent) {
419-
$this->collectLineage($parent->name, $lineage);
457+
$this->collectLineage($parent->name, $lineage, $allowContainer);
420458
}
421459

422460
$lineage[$class] = substr($exportedFile, 1, -1);
@@ -474,13 +512,14 @@ private function addServiceInclude(string $cId, Definition $definition): string
474512
}
475513

476514
foreach (array_diff_key(array_flip($lineage), $this->inlinedRequires) as $file => $class) {
477-
$code .= sprintf(" include_once %s;\n", $file);
515+
$code .= sprintf(" include_once %s;\n", preg_replace('#^\\$this->targetDirs\[(\d++)\]#', sprintf('\dirname(__DIR__, %d + $1)', $this->asFiles), $file));
478516
}
479517
}
480518

481519
foreach ($this->inlinedDefinitions as $def) {
482520
if ($file = $def->getFile()) {
483-
$code .= sprintf(" include_once %s;\n", $this->dumpValue($file));
521+
$file = $this->dumpValue($file);
522+
$code .= sprintf(" include_once %s;\n", preg_replace('#^\\$this->targetDirs\[(\d++)\]#', sprintf('\dirname(__DIR__, %d + $1)', $this->asFiles), $file));
484523
}
485524
}
486525

@@ -958,7 +997,7 @@ private function addNewInstance(Definition $definition, string $return = '', str
958997
return $return.sprintf('new %s(%s)', $this->dumpLiteralClass($this->dumpValue($class)), implode(', ', $arguments)).$tail;
959998
}
960999

961-
private function startClass(string $class, string $baseClass, string $baseClassWithNamespace): string
1000+
private function startClass(string $class, string $baseClass, string $baseClassWithNamespace, ?string &$preload): string
9621001
{
9631002
$namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : '';
9641003

@@ -1026,7 +1065,11 @@ public function __construct()
10261065
$code .= $this->addMethodMap();
10271066
$code .= $this->asFiles ? $this->addFileMap() : '';
10281067
$code .= $this->addAliases();
1029-
$code .= $this->addInlineRequires();
1068+
1069+
if ($preload = $this->getInlineRequires()) {
1070+
$code .= sprintf("\n \$this->privates['service_container'] = static function () {%s\n };\n", $this->asFiles ? "\n require_once __DIR__.'/preload.php';" : $preload);
1071+
}
1072+
10301073
$code .= <<<EOF
10311074
}
10321075
@@ -1227,7 +1270,7 @@ protected function {$methodNameAlias}()
12271270
return $code;
12281271
}
12291272

1230-
private function addInlineRequires(): string
1273+
private function getInlineRequires(): string
12311274
{
12321275
if (!$this->hotPathTag || !$this->inlineRequires) {
12331276
return '';
@@ -1251,11 +1294,11 @@ private function addInlineRequires(): string
12511294
foreach ($lineage as $file) {
12521295
if (!isset($this->inlinedRequires[$file])) {
12531296
$this->inlinedRequires[$file] = true;
1254-
$code .= sprintf("\n include_once %s;", $file);
1297+
$code .= sprintf("\n include_once %s;", preg_replace('#^\\$this->targetDirs\[(\d++)\]#', sprintf('\dirname(__DIR__, %d + $1)', $this->asFiles), $file));
12551298
}
12561299
}
12571300

1258-
return $code ? sprintf("\n \$this->privates['service_container'] = function () {%s\n };\n", $code) : '';
1301+
return $code;
12591302
}
12601303

12611304
private function addDefaultParametersMethod(): string

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ public function __construct()
3636

3737
$this->aliases = [];
3838

39-
$this->privates['service_container'] = function () {
40-
include_once $this->targetDirs[1].'/includes/HotPath/I1.php';
41-
include_once $this->targetDirs[1].'/includes/HotPath/P1.php';
42-
include_once $this->targetDirs[1].'/includes/HotPath/T1.php';
43-
include_once $this->targetDirs[1].'/includes/HotPath/C1.php';
39+
$this->privates['service_container'] = static function () {
40+
include_once \dirname(__DIR__, 0 + 1).'/includes/HotPath/I1.php';
41+
include_once \dirname(__DIR__, 0 + 1).'/includes/HotPath/P1.php';
42+
include_once \dirname(__DIR__, 0 + 1).'/includes/HotPath/T1.php';
43+
include_once \dirname(__DIR__, 0 + 1).'/includes/HotPath/C1.php';
4444
};
4545
}
4646

@@ -90,8 +90,8 @@ protected function getC1Service()
9090
*/
9191
protected function getC2Service()
9292
{
93-
include_once $this->targetDirs[1].'/includes/HotPath/C2.php';
94-
include_once $this->targetDirs[1].'/includes/HotPath/C3.php';
93+
include_once \dirname(__DIR__, 0 + 1).'/includes/HotPath/C2.php';
94+
include_once \dirname(__DIR__, 0 + 1).'/includes/HotPath/C3.php';
9595

9696
return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C2'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2(new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3());
9797
}

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