function ProxyHelper::generateLazyGhost
Helps generate lazy-loading ghost objects.
Throws
LogicException When the class is incompatible with ghost objects
2 calls to ProxyHelper::generateLazyGhost()
- LazyServiceDumper::getProxyCode in vendor/
symfony/ dependency-injection/ LazyProxy/ PhpDumper/ LazyServiceDumper.php - Generates the code for the lazy proxy.
- LazyServiceDumper::isProxyCandidate in vendor/
symfony/ dependency-injection/ LazyProxy/ PhpDumper/ LazyServiceDumper.php - Inspects whether the given definitions should produce proxy instantiation logic in the dumped container.
File
-
vendor/
symfony/ var-exporter/ ProxyHelper.php, line 28
Class
- ProxyHelper
- @author Nicolas Grekas <p@tchwork.com>
Namespace
Symfony\Component\VarExporterCode
public static function generateLazyGhost(\ReflectionClass $class) : string {
if (\PHP_VERSION_ID < 80300 && $class->isReadOnly()) {
throw new LogicException(\sprintf('Cannot generate lazy ghost with PHP < 8.3: class "%s" is readonly.', $class->name));
}
if ($class->isFinal()) {
throw new LogicException(\sprintf('Cannot generate lazy ghost: class "%s" is final.', $class->name));
}
if ($class->isInterface() || $class->isAbstract()) {
throw new LogicException(\sprintf('Cannot generate lazy ghost: "%s" is not a concrete class.', $class->name));
}
if (\stdClass::class !== $class->name && $class->isInternal()) {
throw new LogicException(\sprintf('Cannot generate lazy ghost: class "%s" is internal.', $class->name));
}
if ($class->hasMethod('__get') && 'mixed' !== (self::exportType($class->getMethod('__get')) ?? 'mixed')) {
throw new LogicException(\sprintf('Cannot generate lazy ghost: return type of method "%s::__get()" should be "mixed".', $class->name));
}
static $traitMethods;
$traitMethods ??= (new \ReflectionClass(LazyGhostTrait::class))->getMethods();
foreach ($traitMethods as $method) {
if ($class->hasMethod($method->name) && $class->getMethod($method->name)
->isFinal()) {
throw new LogicException(\sprintf('Cannot generate lazy ghost: method "%s::%s()" is final.', $class->name, $method->name));
}
}
$parent = $class;
while ($parent = $parent->getParentClass()) {
if (\stdClass::class !== $parent->name && $parent->isInternal()) {
throw new LogicException(\sprintf('Cannot generate lazy ghost: class "%s" extends "%s" which is internal.', $class->name, $parent->name));
}
}
$propertyScopes = self::exportPropertyScopes($class->name);
return <<<EOPHP
extends \\{<span class="php-variable">$class</span>-><span class="php-function-or-constant property member-of-variable">name</span>} implements \\Symfony\\Component\\VarExporter\\LazyObjectInterface
{
use \\Symfony\\Component\\VarExporter\\LazyGhostTrait;
private const LAZY_OBJECT_PROPERTY_SCOPES = {<span class="php-variable">$propertyScopes</span>};
}
// Help opcache.preload discover always-needed symbols
class_exists(\\Symfony\\Component\\VarExporter\\Internal\\Hydrator::class);
class_exists(\\Symfony\\Component\\VarExporter\\Internal\\LazyObjectRegistry::class);
class_exists(\\Symfony\\Component\\VarExporter\\Internal\\LazyObjectState::class);
EOPHP;
}