32
32
use Symfony \Component \DependencyInjection \LazyProxy \PhpDumper \DumperInterface as ProxyDumper ;
33
33
use Symfony \Component \DependencyInjection \LazyProxy \PhpDumper \NullDumper ;
34
34
use Symfony \Component \DependencyInjection \Parameter ;
35
+ use Symfony \Component \DependencyInjection \ParameterBag \EnvPlaceholderParameterBag ;
35
36
use Symfony \Component \DependencyInjection \Reference ;
36
37
use Symfony \Component \DependencyInjection \ServiceLocator as BaseServiceLocator ;
37
38
use Symfony \Component \DependencyInjection \TypedReference ;
@@ -216,7 +217,7 @@ public function dump(array $options = [])
216
217
}
217
218
218
219
$ code =
219
- $ this ->startClass ($ options ['class ' ], $ baseClass , $ baseClassWithNamespace ).
220
+ $ this ->startClass ($ options ['class ' ], $ baseClass , $ baseClassWithNamespace, $ preload ).
220
221
$ this ->addServices ($ services ).
221
222
$ this ->addDeprecatedAliases ().
222
223
$ this ->addDefaultParametersMethod ()
@@ -243,6 +244,10 @@ public function dump(array $options = [])
243
244
EOF ;
244
245
$ files = [];
245
246
247
+ if ($ preload ) {
248
+ $ files ['preload.php ' ] = "<?php \n" .str_replace ("\n include_once " , "\ninclude_once " , $ preload )."\n" ;
249
+ }
250
+
246
251
$ ids = $ this ->container ->getRemovedIds ();
247
252
foreach ($ this ->container ->getDefinitions () as $ id => $ definition ) {
248
253
if (!$ definition ->isPublic ()) {
@@ -277,6 +282,34 @@ public function dump(array $options = [])
277
282
$ time = $ options ['build_time ' ];
278
283
$ id = hash ('crc32 ' , $ hash .$ time );
279
284
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
+ require __DIR__.'/Container {$ hash }/preload.php';
293
+
294
+ EOF ;
295
+
296
+ $ lineage = [];
297
+
298
+ $ this ->collectLineage ($ baseClassWithNamespace , $ lineage , true );
299
+ $ this ->collectLineage (EnvPlaceholderParameterBag::class, $ lineage );
300
+
301
+ $ lineage [] = "__DIR__.'/Container {$ hash }/ {$ options ['class ' ]}.php' " ;
302
+
303
+ foreach ($ lineage as $ file ) {
304
+ if (!isset ($ this ->inlinedRequires [$ file ])) {
305
+ $ this ->inlinedRequires [$ file ] = true ;
306
+ $ preload .= sprintf ("include_once %s; \n" , preg_replace ('#^ \\$this->targetDirs\[(\d++)\]# ' , 'dirname(__DIR__, $1) ' , $ file ));
307
+ }
308
+ }
309
+
310
+ $ code [$ options ['class ' ].'.preload.php ' ] = $ preload ;
311
+ }
312
+
280
313
$ code [$ options ['class ' ].'.php ' ] = <<<EOF
281
314
<?php
282
315
{$ namespaceLine }
@@ -391,15 +424,15 @@ private function connectCircularReferences($sourceId, &$currentPath, &$subPath =
391
424
unset($ subPath [$ sourceId ]);
392
425
}
393
426
394
- private function collectLineage ($ class , array &$ lineage )
427
+ private function collectLineage ($ class , array &$ lineage, bool $ allowContainer = false )
395
428
{
396
429
if (isset ($ lineage [$ class ])) {
397
430
return ;
398
431
}
399
432
if (!$ r = $ this ->container ->getReflectionClass ($ class , false )) {
400
433
return ;
401
434
}
402
- if ($ this ->container instanceof $ class ) {
435
+ if (! $ allowContainer && $ this ->container instanceof $ class ) {
403
436
return ;
404
437
}
405
438
$ file = $ r ->getFileName ();
@@ -408,15 +441,15 @@ private function collectLineage($class, array &$lineage)
408
441
}
409
442
410
443
if ($ parent = $ r ->getParentClass ()) {
411
- $ this ->collectLineage ($ parent ->name , $ lineage );
444
+ $ this ->collectLineage ($ parent ->name , $ lineage, $ allowContainer );
412
445
}
413
446
414
447
foreach ($ r ->getInterfaces () as $ parent ) {
415
- $ this ->collectLineage ($ parent ->name , $ lineage );
448
+ $ this ->collectLineage ($ parent ->name , $ lineage, $ allowContainer );
416
449
}
417
450
418
451
foreach ($ r ->getTraits () as $ parent ) {
419
- $ this ->collectLineage ($ parent ->name , $ lineage );
452
+ $ this ->collectLineage ($ parent ->name , $ lineage, $ allowContainer );
420
453
}
421
454
422
455
$ lineage [$ class ] = substr ($ exportedFile , 1 , -1 );
@@ -474,13 +507,14 @@ private function addServiceInclude(string $cId, Definition $definition): string
474
507
}
475
508
476
509
foreach (array_diff_key (array_flip ($ lineage ), $ this ->inlinedRequires ) as $ file => $ class ) {
477
- $ code .= sprintf (" include_once %s; \n" , $ file );
510
+ $ code .= sprintf (" include_once %s; \n" , preg_replace ( ' #^ \\ $this->targetDirs\[(\d++)\]# ' , sprintf ( ' \dirname(__DIR__, %d + $1) ' , $ this -> asFiles ), $ file) );
478
511
}
479
512
}
480
513
481
514
foreach ($ this ->inlinedDefinitions as $ def ) {
482
515
if ($ file = $ def ->getFile ()) {
483
- $ code .= sprintf (" include_once %s; \n" , $ this ->dumpValue ($ file ));
516
+ $ file = $ this ->dumpValue ($ file );
517
+ $ code .= sprintf (" include_once %s; \n" , preg_replace ('#^ \\$this->targetDirs\[(\d++)\]# ' , sprintf ('\dirname(__DIR__, %d + $1) ' , $ this ->asFiles ), $ file ));
484
518
}
485
519
}
486
520
@@ -958,7 +992,7 @@ private function addNewInstance(Definition $definition, string $return = '', str
958
992
return $ return .sprintf ('new %s(%s) ' , $ this ->dumpLiteralClass ($ this ->dumpValue ($ class )), implode (', ' , $ arguments )).$ tail ;
959
993
}
960
994
961
- private function startClass (string $ class , string $ baseClass , string $ baseClassWithNamespace ): string
995
+ private function startClass (string $ class , string $ baseClass , string $ baseClassWithNamespace, ? string & $ preload ): string
962
996
{
963
997
$ namespaceLine = !$ this ->asFiles && $ this ->namespace ? "\nnamespace {$ this ->namespace }; \n" : '' ;
964
998
@@ -1026,7 +1060,11 @@ public function __construct()
1026
1060
$ code .= $ this ->addMethodMap ();
1027
1061
$ code .= $ this ->asFiles ? $ this ->addFileMap () : '' ;
1028
1062
$ code .= $ this ->addAliases ();
1029
- $ code .= $ this ->addInlineRequires ();
1063
+
1064
+ if ($ preload = $ this ->getInlineRequires ()) {
1065
+ $ code .= sprintf ("\n \$this->privates['service_container'] = static function () {%s \n }; \n" , $ this ->asFiles ? "\n require_once __DIR__.'/preload.php'; " : $ preload );
1066
+ }
1067
+
1030
1068
$ code .= <<<EOF
1031
1069
}
1032
1070
@@ -1227,7 +1265,7 @@ protected function {$methodNameAlias}()
1227
1265
return $ code ;
1228
1266
}
1229
1267
1230
- private function addInlineRequires (): string
1268
+ private function getInlineRequires (): string
1231
1269
{
1232
1270
if (!$ this ->hotPathTag || !$ this ->inlineRequires ) {
1233
1271
return '' ;
@@ -1251,11 +1289,11 @@ private function addInlineRequires(): string
1251
1289
foreach ($ lineage as $ file ) {
1252
1290
if (!isset ($ this ->inlinedRequires [$ file ])) {
1253
1291
$ this ->inlinedRequires [$ file ] = true ;
1254
- $ code .= sprintf ("\n include_once %s; " , $ file );
1292
+ $ code .= sprintf ("\n include_once %s; " , preg_replace ( ' #^ \\ $this->targetDirs\[(\d++)\]# ' , sprintf ( ' \dirname(__DIR__, %d + $1) ' , $ this -> asFiles ), $ file) );
1255
1293
}
1256
1294
}
1257
1295
1258
- return $ code ? sprintf ( "\n \$ this->privates['service_container'] = function () {%s \n }; \n" , $ code ) : '' ;
1296
+ return $ code ;
1259
1297
}
1260
1298
1261
1299
private function addDefaultParametersMethod (): string
0 commit comments