Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e33a0b0

Browse files
[DI] fix dumping non-shared lazy services
1 parent 2a5710f commit e33a0b0

File tree

4 files changed

+68
-16
lines changed

4 files changed

+68
-16
lines changed

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

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -863,18 +863,45 @@ protected function {$methodName}($lazyInitialization)
863863
}
864864
}
865865

866-
if ($this->getProxyDumper()->isProxyCandidate($definition)) {
867-
$factoryCode = $definition->isShared() ? ($asFile ? "\$this->load('%s', false)" : '$this->%s(false)') : '$this->factories[%2$s](false)';
868-
$factoryCode = $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName, $this->doExport($id)));
866+
if (!$definition->isShared()) {
867+
$factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id));
868+
}
869+
870+
if ($isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition)) {
871+
if (!$definition->isShared()) {
872+
$code .= sprintf(' %s = %1$s ?? ', $factory);
873+
874+
if ($asFile) {
875+
$code .= "function () {\n";
876+
$code .= " return self::do(\$container);\n";
877+
$code .= " };\n\n";
878+
} else {
879+
$code .= sprintf("\\Closure::fromCallable([\$this, '%s']);\n\n", $methodName);
880+
}
881+
}
882+
883+
$factoryCode = $asFile ? 'self::do($container, false)' : sprintf('$this->%s(false)', $methodName);
884+
$factoryCode = $this->getProxyDumper()->getProxyFactoryCode($definition, $id, $factoryCode);
869885
$code .= $asFile ? preg_replace('/function \(([^)]*+)\) {/', 'function (\1) use ($container) {', $factoryCode) : $factoryCode;
870886
}
871887

872-
$code .= $this->addServiceInclude($id, $definition);
888+
$c = $this->addServiceInclude($id, $definition);
889+
890+
if ('' !== $c && $isProxyCandidate && !$definition->isShared()) {
891+
$c = implode("\n", array_map(function ($line) { return $line ? ' '.$line : $line; }, explode("\n", $c)));
892+
$code .= " static \$include = true;\n\n";
893+
$code .= " if (\$include) {\n";
894+
$code .= $c;
895+
$code .= " \$include = false;\n";
896+
$code .= " }\n\n";
897+
} else {
898+
$code .= $c;
899+
}
900+
873901
$c = $this->addInlineService($id, $definition);
874902

875-
if (!$definition->isShared()) {
903+
if (!$isProxyCandidate && !$definition->isShared()) {
876904
$c = implode("\n", array_map(function ($line) { return $line ? ' '.$line : $line; }, explode("\n", $c)));
877-
$factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id));
878905
$lazyloadInitialization = $definition->isLazy() ? '$lazyLoad = true' : '';
879906

880907
$c = sprintf(" %s = function (%s) {\n%s };\n\n return %1\$s();\n", $factory, $lazyloadInitialization, $c);

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ public function testNonSharedLazyDumpAsFiles()
307307
->setLazy(true);
308308
$container->compile();
309309
$dumper = new PhpDumper($container);
310+
$dumper->setProxyDumper(new \DummyProxyDumper());
310311
$dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__, 'inline_factories_parameter' => false, 'inline_class_loader_parameter' => false]), true);
311312

312313
if ('\\' === \DIRECTORY_SEPARATOR) {

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,11 @@ protected function getBarService()
6767
*/
6868
protected function getFooService($lazyLoad = true)
6969
{
70-
// lazy factory for stdClass
70+
$this->factories['service_container']['foo'] = $this->factories['service_container']['foo'] ?? \Closure::fromCallable([$this, 'getFooService']);
7171

72-
$this->factories['service_container']['foo'] = function ($lazyLoad = true) {
73-
return new \stdClass();
74-
};
72+
// lazy factory for stdClass
7573

76-
return $this->factories['service_container']['foo']();
74+
return new \stdClass();
7775
}
7876
}
7977

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_non_shared_lazy_as_files.txt

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,34 @@ class getNonSharedFooService extends ProjectServiceContainer
2828
*/
2929
public static function do($container, $lazyLoad = true)
3030
{
31-
include_once $container->targetDir.''.'/Fixtures/includes/foo_lazy.php';
32-
33-
$container->factories['non_shared_foo'] = function ($lazyLoad = true) use ($container) {
34-
return new \Bar\FooLazyClass();
31+
$container->factories['non_shared_foo'] = $container->factories['non_shared_foo'] ?? function () use ($container) {
32+
return self::do($container);
3533
};
3634

37-
return $container->factories['non_shared_foo']();
35+
// lazy factory for Bar\FooLazyClass
36+
37+
static $include = true;
38+
39+
if ($include) {
40+
include_once $container->targetDir.''.'/Fixtures/includes/foo_lazy.php';
41+
42+
$include = false;
43+
}
44+
45+
return new \Bar\FooLazyClass();
3846
}
3947
}
4048

49+
[Container%s/proxy.php] => <?php
50+
51+
namespace Container%s;
52+
53+
// proxy code for Bar\FooLazyClass
54+
55+
if (!\class_exists('proxy', false)) {
56+
\class_alias(__NAMESPACE__.'\\proxy', 'proxy', false);
57+
}
58+
4159
[Container%s/ProjectServiceContainer.php] => <?php
4260

4361
namespace Container%s;
@@ -105,6 +123,13 @@ class ProjectServiceContainer extends Container
105123

106124
return class_exists($class, false) ? $class::do($this, $lazyLoad) : $service;
107125
}
126+
127+
protected function createProxy($class, \Closure $factory)
128+
{
129+
class_exists($class, false) || require __DIR__.'/'.$class.'.php';
130+
131+
return $factory();
132+
}
108133
}
109134

110135
[ProjectServiceContainer.preload.php] => <?php
@@ -120,6 +145,7 @@ if (in_array(PHP_SAPI, ['cli', 'phpdbg'], true)) {
120145

121146
require dirname(__DIR__, %d).'%svendor/autoload.php';
122147
require __DIR__.'/Container%s/ProjectServiceContainer.php';
148+
require __DIR__.'/Container%s/proxy.php';
123149
require __DIR__.'/Container%s/getNonSharedFooService.php';
124150

125151
$classes = [];

0 commit comments

Comments
 (0)