@@ -68,7 +68,7 @@ class PhpDumper extends Dumper
68
68
private $ variableCount ;
69
69
private $ inlinedDefinitions ;
70
70
private $ serviceCalls ;
71
- private $ reservedVariables = ['instance ' , 'class ' , 'this ' ];
71
+ private $ reservedVariables = ['instance ' , 'class ' , 'this ' , ' container ' ];
72
72
private $ expressionLanguage ;
73
73
private $ targetDirRegex ;
74
74
private $ targetDirMaxMatches ;
@@ -246,20 +246,24 @@ public function dump(array $options = [])
246
246
if ($ this ->addGetService ) {
247
247
$ code = preg_replace (
248
248
"/( \r? \n\r? \n public function __construct.+? \\{ \r? \n)/s " ,
249
- "\n private \$getService;$1 \$this->getService = \\Closure::fromCallable([ \$this, 'getService']); \n" ,
249
+ "\n protected \$getService;$1 \$this->getService = \\Closure::fromCallable([ \$this, 'getService']); \n" ,
250
250
$ code ,
251
251
1
252
252
);
253
253
}
254
254
255
255
if ($ this ->asFiles ) {
256
- $ fileStart = <<<EOF
256
+ $ fileTemplate = <<<EOF
257
257
<?php
258
258
259
259
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
260
260
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
261
261
262
- // This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
262
+ /* {$ this ->docStar }
263
+ * @internal This class has been auto-generated by the Symfony Dependency Injection Component.
264
+ */
265
+ class %s extends {$ options ['class ' ]}
266
+ {%s}
263
267
264
268
EOF ;
265
269
$ files = [];
@@ -281,7 +285,7 @@ public function dump(array $options = [])
281
285
282
286
if (!$ this ->inlineFactories ) {
283
287
foreach ($ this ->generateServiceFiles ($ services ) as $ file => $ c ) {
284
- $ files [$ file ] = $ fileStart . $ c ;
288
+ $ files [$ file ] = sprintf ( $ fileTemplate , substr ( $ file , 0 , - 4 ), $ c ) ;
285
289
}
286
290
foreach ($ proxyClasses as $ file => $ c ) {
287
291
$ files [$ file ] = "<?php \n" .$ c ;
@@ -301,10 +305,8 @@ public function dump(array $options = [])
301
305
$ code = [];
302
306
303
307
foreach ($ files as $ file => $ c ) {
304
- $ code ["Container {$ hash }/ {$ file }" ] = $ c ;
308
+ $ code ["Container {$ hash }/ {$ file }" ] = substr_replace ( $ c , " <?php \n\n namespace Container { $ hash } ; \n" , 0 , 6 ) ;
305
309
}
306
- array_pop ($ code );
307
- $ code ["Container {$ hash }/ {$ options ['class ' ]}.php " ] = substr_replace ($ files [$ options ['class ' ].'.php ' ], "<?php \n\nnamespace Container {$ hash }; \n" , 0 , 6 );
308
310
$ namespaceLine = $ this ->namespace ? "\nnamespace {$ this ->namespace }; \n" : '' ;
309
311
$ time = $ options ['build_time ' ];
310
312
$ id = hash ('crc32 ' , $ hash .$ time );
@@ -313,6 +315,9 @@ public function dump(array $options = [])
313
315
if ($ this ->preload && null !== $ autoloadFile = $ this ->getAutoloadFile ()) {
314
316
$ autoloadFile = substr ($ this ->export ($ autoloadFile ), 2 , -1 );
315
317
318
+ $ factoryFiles = array_reverse (array_keys ($ code ));
319
+ $ factoryFiles = implode ("'; \nrequire __DIR__.'/ " , $ factoryFiles );
320
+
316
321
$ code [$ options ['class ' ].'.preload.php ' ] = <<<EOF
317
322
<?php
318
323
@@ -322,7 +327,7 @@ public function dump(array $options = [])
322
327
use Symfony\Component\DependencyInjection\Dumper\Preloader;
323
328
324
329
require $ autoloadFile;
325
- require __DIR__.'/Container { $ hash } / { $ options [ ' class ' ]} .php ';
330
+ require __DIR__.'/ $ factoryFiles ';
326
331
327
332
\$classes = [];
328
333
@@ -546,7 +551,13 @@ private function generateProxyClasses(): array
546
551
$ proxyCode = substr (Kernel::stripComments ($ proxyCode ), 5 );
547
552
}
548
553
549
- $ proxyClasses [sprintf ('%s.php ' , explode (' ' , $ this ->inlineRequires ? substr ($ proxyCode , \strlen ($ code )) : $ proxyCode , 3 )[1 ])] = $ proxyCode ;
554
+ $ proxyClass = explode (' ' , $ this ->inlineRequires ? substr ($ proxyCode , \strlen ($ code )) : $ proxyCode , 3 )[1 ];
555
+
556
+ if ($ this ->asFiles || $ this ->namespace ) {
557
+ $ proxyCode .= "\n\\class_alias(__NAMESPACE__.' \\\\$ proxyClass', ' $ proxyClass', false); \n" ;
558
+ }
559
+
560
+ $ proxyClasses [$ proxyClass .'.php ' ] = $ proxyCode ;
550
561
}
551
562
552
563
return $ proxyClasses ;
@@ -784,21 +795,16 @@ private function addService(string $id, Definition $definition): array
784
795
$ shared = $ definition ->isShared () ? ' shared ' : '' ;
785
796
$ public = $ definition ->isPublic () ? 'public ' : 'private ' ;
786
797
$ autowired = $ definition ->isAutowired () ? ' autowired ' : '' ;
798
+ $ asFile = $ this ->asFiles && !$ this ->inlineFactories && !$ this ->isHotPath ($ definition );
799
+ $ methodName = $ this ->generateMethodName ($ id );
787
800
788
- if ($ definition ->isLazy ()) {
801
+ if ($ asFile || $ definition ->isLazy ()) {
789
802
$ lazyInitialization = '$lazyLoad = true ' ;
790
803
} else {
791
804
$ lazyInitialization = '' ;
792
805
}
793
806
794
- $ asFile = $ this ->asFiles && !$ this ->inlineFactories && !$ this ->isHotPath ($ definition );
795
- $ methodName = $ this ->generateMethodName ($ id );
796
- if ($ asFile ) {
797
- $ file = $ methodName .'.php ' ;
798
- $ code = " // Returns the $ public ' $ id' $ shared$ autowired service. \n\n" ;
799
- } else {
800
- $ file = null ;
801
- $ code = <<<EOF
807
+ $ code = <<<EOF
802
808
803
809
/* {$ this ->docStar }
804
810
* Gets the $ public ' $ id' $ shared$ autowired service.
@@ -812,6 +818,12 @@ protected function {$methodName}($lazyInitialization)
812
818
{
813
819
814
820
EOF ;
821
+
822
+ if ($ asFile ) {
823
+ $ file = $ methodName .'.php ' ;
824
+ $ code = str_replace ("protected function {$ methodName }( " , 'public static function do($container, ' , $ code );
825
+ } else {
826
+ $ file = null ;
815
827
}
816
828
817
829
if ($ definition ->hasErrors () && $ e = $ definition ->getErrors ()) {
@@ -833,20 +845,21 @@ protected function {$methodName}($lazyInitialization)
833
845
}
834
846
835
847
if ($ this ->getProxyDumper ()->isProxyCandidate ($ definition )) {
836
- $ factoryCode = $ asFile ? ( $ definition -> isShared () ? "\$this->load('%s.php ', false) " : ' $this->factories[%2$s](false) ' ) : '$this->%s(false) ' ;
837
- $ code .= $ this ->getProxyDumper ()->getProxyFactoryCode ($ definition , $ id , sprintf ($ factoryCode , $ methodName, $ this -> doExport ( $ id ) ));
848
+ $ factoryCode = $ asFile ? "\$this->load('%s', false) " : '$this->%s(false) ' ;
849
+ $ code .= $ this ->getProxyDumper ()->getProxyFactoryCode ($ definition , $ id , sprintf ($ factoryCode , $ methodName ));
838
850
}
839
851
840
852
$ code .= $ this ->addServiceInclude ($ id , $ definition );
841
853
$ code .= $ this ->addInlineService ($ id , $ definition );
842
854
}
843
855
844
856
if ($ asFile ) {
845
- $ code = implode ("\n" , array_map (function ($ line ) { return $ line ? substr ($ line , 8 ) : $ line ; }, explode ("\n" , $ code )));
846
- } else {
847
- $ code .= " } \n" ;
857
+ $ code = str_replace ('$this ' , '$container ' , $ code );
858
+ $ code = str_replace ('function () { ' , 'function () use ($container) { ' , $ code );
848
859
}
849
860
861
+ $ code .= " } \n" ;
862
+
850
863
$ this ->definitionVariables = $ this ->inlinedDefinitions = null ;
851
864
$ this ->referenceVariables = $ this ->serviceCalls = null ;
852
865
@@ -1017,21 +1030,6 @@ private function generateServiceFiles(array $services): iterable
1017
1030
ksort ($ definitions );
1018
1031
foreach ($ definitions as $ id => $ definition ) {
1019
1032
if ((list ($ file , $ code ) = $ services [$ id ]) && null !== $ file && ($ definition ->isPublic () || !$ this ->isTrivialInstance ($ definition ) || isset ($ this ->locatedIds [$ id ]))) {
1020
- if (!$ definition ->isShared ()) {
1021
- $ i = strpos ($ code , "\n\ninclude_once " );
1022
- if (false !== $ i && false !== $ i = strpos ($ code , "\n\n" , 2 + $ i )) {
1023
- $ code = [substr ($ code , 0 , 2 + $ i ), substr ($ code , 2 + $ i )];
1024
- } else {
1025
- $ code = ["\n" , $ code ];
1026
- }
1027
- $ code [1 ] = implode ("\n" , array_map (function ($ line ) { return $ line ? ' ' .$ line : $ line ; }, explode ("\n" , $ code [1 ])));
1028
- $ factory = sprintf ('$this->factories%s[%s] ' , $ definition ->isPublic () ? '' : "['service_container'] " , $ this ->doExport ($ id ));
1029
- $ lazyloadInitialization = $ definition ->isLazy () ? '$lazyLoad = true ' : '' ;
1030
-
1031
- $ code [1 ] = sprintf ("%s = function (%s) { \n%s}; \n\nreturn %1 \$s(); \n" , $ factory , $ lazyloadInitialization , $ code [1 ]);
1032
- $ code = $ code [0 ].$ code [1 ];
1033
- }
1034
-
1035
1033
yield $ file => $ code ;
1036
1034
}
1037
1035
}
@@ -1112,27 +1110,24 @@ private function startClass(string $class, string $baseClass): string
1112
1110
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
1113
1111
1114
1112
/* {$ this ->docStar }
1115
- * This class has been auto-generated
1116
- * by the Symfony Dependency Injection Component.
1117
- *
1118
- * @final
1113
+ * @internal This class has been auto-generated by the Symfony Dependency Injection Component.
1119
1114
*/
1120
1115
class $ class extends $ baseClass
1121
1116
{
1122
- private \$parameters = [];
1117
+ protected \$parameters = [];
1123
1118
1124
1119
public function __construct()
1125
1120
{
1126
1121
1127
1122
EOF ;
1128
1123
if ($ this ->asFiles ) {
1129
- $ code = str_replace ('$parameters ' , "\$buildParameters ; \n private \$containerDir ; \n private \$parameters " , $ code );
1124
+ $ code = str_replace ('$parameters = [] ' , "\$containerDir ; \n protected \$parameters = [] ; \n private \$buildParameters " , $ code );
1130
1125
$ code = str_replace ('__construct() ' , '__construct(array $buildParameters = [], $containerDir = __DIR__) ' , $ code );
1131
1126
$ code .= " \$this->buildParameters = \$buildParameters; \n" ;
1132
1127
$ code .= " \$this->containerDir = \$containerDir; \n" ;
1133
1128
1134
1129
if (null !== $ this ->targetDirRegex ) {
1135
- $ code = str_replace ('$parameters ' , "\$targetDir; \n private \$parameters " , $ code );
1130
+ $ code = str_replace ('$parameters = [] ' , "\$targetDir; \n protected \$parameters = [] " , $ code );
1136
1131
$ code .= ' $this->targetDir = \\dirname($containerDir); ' ."\n" ;
1137
1132
}
1138
1133
}
@@ -1176,11 +1171,23 @@ public function isCompiled(): bool
1176
1171
$ code .= $ this ->addRemovedIds ();
1177
1172
1178
1173
if ($ this ->asFiles && !$ this ->inlineFactories ) {
1179
- $ code .= <<<EOF
1174
+ $ code .= <<<' EOF'
1180
1175
1181
- protected function load( \ $file, \ $lazyLoad = true)
1176
+ protected function load($file, $lazyLoad = true)
1182
1177
{
1183
- return require \$this->containerDir.\\DIRECTORY_SEPARATOR. \$file;
1178
+ if (class_exists($class = __NAMESPACE__.'\\'.$file, false)) {
1179
+ return $class::do($this, $lazyLoad);
1180
+ }
1181
+
1182
+ if ('.' === $file[-4]) {
1183
+ $class = substr($class, 0, -4);
1184
+ } else {
1185
+ $file .= '.php';
1186
+ }
1187
+
1188
+ $service = require $this->containerDir.\DIRECTORY_SEPARATOR.$file;
1189
+
1190
+ return class_exists($class, false) ? $class::do($this, $lazyLoad) : $service;
1184
1191
}
1185
1192
1186
1193
EOF;
@@ -1191,16 +1198,13 @@ protected function load(\$file, \$lazyLoad = true)
1191
1198
if (!$ proxyDumper ->isProxyCandidate ($ definition )) {
1192
1199
continue ;
1193
1200
}
1201
+
1194
1202
if ($ this ->asFiles && !$ this ->inlineFactories ) {
1195
- $ proxyLoader = '$this->load("{$class}.php") ' ;
1196
- } elseif ($ this ->namespace || $ this ->inlineFactories ) {
1197
- $ proxyLoader = 'class_alias(__NAMESPACE__." \\\\$class", $class, false) ' ;
1203
+ $ proxyLoader = "class_exists( \$class, false) || require __DIR__.'/'. \$class.'.php'; \n\n " ;
1198
1204
} else {
1199
1205
$ proxyLoader = '' ;
1200
1206
}
1201
- if ($ proxyLoader ) {
1202
- $ proxyLoader = "class_exists( \$class, false) || {$ proxyLoader }; \n\n " ;
1203
- }
1207
+
1204
1208
$ code .= <<<EOF
1205
1209
1206
1210
protected function createProxy( \$class, \Closure \$factory)
@@ -1295,7 +1299,7 @@ private function addFileMap(): string
1295
1299
ksort ($ definitions );
1296
1300
foreach ($ definitions as $ id => $ definition ) {
1297
1301
if (!$ definition ->isSynthetic () && $ definition ->isPublic () && !$ this ->isHotPath ($ definition )) {
1298
- $ code .= sprintf (" %s => '%s.php ', \n" , $ this ->doExport ($ id ), $ this ->generateMethodName ($ id ));
1302
+ $ code .= sprintf (" %s => '%s', \n" , $ this ->doExport ($ id ), $ this ->generateMethodName ($ id ));
1299
1303
}
1300
1304
}
1301
1305
@@ -1709,7 +1713,7 @@ private function dumpValue($value, bool $interpolate = true): string
1709
1713
$ this ->export ($ k ),
1710
1714
$ this ->export ($ definition ->isShared () ? ($ definition ->isPublic () ? 'services ' : 'privates ' ) : false ),
1711
1715
$ this ->doExport ($ id ),
1712
- $ this ->export (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $ v ->getInvalidBehavior () && !\is_string ($ load ) ? $ this ->generateMethodName ($ id ).( $ load ? ' .php ' : '' ) : null ),
1716
+ $ this ->export (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $ v ->getInvalidBehavior () && !\is_string ($ load ) ? $ this ->generateMethodName ($ id ) : null ),
1713
1717
$ this ->export ($ load )
1714
1718
);
1715
1719
$ serviceTypes .= sprintf ("\n %s => %s, " , $ this ->export ($ k ), $ this ->export ($ v instanceof TypedReference ? $ v ->getType () : '? ' ));
@@ -1850,11 +1854,7 @@ private function getServiceCall(string $id, Reference $reference = null): string
1850
1854
}
1851
1855
$ code = "( $ code) " ;
1852
1856
} elseif ($ this ->asFiles && !$ this ->inlineFactories && !$ this ->isHotPath ($ definition )) {
1853
- $ code = sprintf ("\$this->load('%s.php') " , $ this ->generateMethodName ($ id ));
1854
- if (!$ definition ->isShared ()) {
1855
- $ factory = sprintf ('$this->factories%s[%s] ' , $ definition ->isPublic () ? '' : "['service_container'] " , $ this ->doExport ($ id ));
1856
- $ code = sprintf ('(isset(%s) ? %1$s() : %s) ' , $ factory , $ code );
1857
- }
1857
+ $ code = sprintf ("\$this->load('%s') " , $ this ->generateMethodName ($ id ));
1858
1858
} else {
1859
1859
$ code = sprintf ('$this->%s() ' , $ this ->generateMethodName ($ id ));
1860
1860
}
@@ -2045,6 +2045,14 @@ private function doExport($value, bool $resolveEnv = false)
2045
2045
} else {
2046
2046
$ export = var_export ($ value , true );
2047
2047
}
2048
+ if ($ this ->asFiles ) {
2049
+ if (false !== strpos ($ export , '$this ' )) {
2050
+ $ export = str_replace ('$this ' , "$'.'this " , $ export );
2051
+ }
2052
+ if (false !== strpos ($ export , 'function () { ' )) {
2053
+ $ export = str_replace ('function () { ' , "function ('.') { " , $ export );
2054
+ }
2055
+ }
2048
2056
2049
2057
if ($ resolveEnv && "' " === $ export [0 ] && $ export !== $ resolvedExport = $ this ->container ->resolveEnvPlaceholders ($ export , "'. \$this->getEnv('string:%s').' " )) {
2050
2058
$ export = $ resolvedExport ;
0 commit comments