-
Notifications
You must be signed in to change notification settings - Fork 0
Comparison
Olivier Laviale edited this page Oct 14, 2018
·
1 revision
Disclaimer: olvlvl's proxy generator is only that effective because it's designed to generate proxies for Symfony's dependency injection component, and cannot proxy services that don't have any interface, while symfony/proxy-manager-bridge uses ocramius/proxy-manager, which is a complete solution to create proxies, and not only DIC ones.
Please consider the following interface, its implementation, and some builder code:
<?php
namespace cases;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
interface SampleInterface
{
public function getValue(): string;
}
class Sample implements SampleInterface
{
/**
* @var string
*/
private $value;
public function __construct(string $value)
{
$this->value = $value;
}
/**
* @inheritdoc
*/
public function getValue(): string
{
return $this->value;
}
}
$builder = new ContainerBuilder();
$builder->addDefinitions([
SampleInterface::class => (new Definition)
->setClass(Sample::class)
->setLazy(true)
->setPublic(true)
->addArgument('aValue')
]);
$builder->compile();
This is what the dumped container looks like with olvlvl's proxy generator:
<?php
// …
protected function getSampleInterfaceService($lazyLoad = true)
{
if ($lazyLoad) {
return $this->services['cases\SampleInterface'] = new class(
function () {
return $this->getSampleInterfaceService(false);
}
) implements \cases\SampleInterface
{
private $factory, $service;
public function __construct(callable $factory)
{
$this->factory = $factory;
}
public function getValue(): string
{
return ($this->service ?: $this->service = ($this->factory)())->getValue();
}
};
}
return new \cases\Sample('aValue');
}
}
And this is what it looks like with Symfony's:
<?php
// …
protected function getSampleInterfaceService($lazyLoad = true)
{
if ($lazyLoad) {
return $this->services['cases\SampleInterface'] = $this->createProxy('Sample_5107301', function () {
return \Sample_5107301::staticProxyConstructor(function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) {
$wrappedInstance = $this->getSampleInterfaceService(false);
$proxy->setProxyInitializer(null);
return true;
});
});
}
return new \cases\Sample('aValue');
}
}
class Sample_5107301 extends \cases\Sample implements \ProxyManager\Proxy\VirtualProxyInterface
{
/**
* @var \Closure|null initializer responsible for generating the wrapped object
*/
private $valueHolder85aa8 = null;
/**
* @var \Closure|null initializer responsible for generating the wrapped object
*/
private $initializere3f84 = null;
/**
* @var bool[] map of public properties of the parent class
*/
private static $publicPropertiese979b = [
];
public function getValue() : string
{
$this->initializere3f84 && ($this->initializere3f84->__invoke($valueHolder85aa8, $this, 'getValue', array(), $this->initializere3f84) || 1) && $this->valueHolder85aa8 = $valueHolder85aa8;
return $this->valueHolder85aa8->getValue();
}
/**
* Constructor for lazy initialization
*
* @param \Closure|null $initializer
*/
public static function staticProxyConstructor($initializer)
{
static $reflection;
$reflection = $reflection ?? $reflection = new \ReflectionClass(__CLASS__);
$instance = $reflection->newInstanceWithoutConstructor();
\Closure::bind(function (\cases\Sample $instance) {
unset($instance->value);
}, $instance, 'cases\\Sample')->__invoke($instance);
$instance->initializere3f84 = $initializer;
return $instance;
}
public function __construct(string $value)
{
static $reflection;
if (! $this->valueHolder85aa8) {
$reflection = $reflection ?: new \ReflectionClass('cases\\Sample');
$this->valueHolder85aa8 = $reflection->newInstanceWithoutConstructor();
\Closure::bind(function (\cases\Sample $instance) {
unset($instance->value);
}, $this, 'cases\\Sample')->__invoke($this);
}
$this->valueHolder85aa8->__construct($value);
}
public function & __get($name)
{
$this->initializere3f84 && ($this->initializere3f84->__invoke($valueHolder85aa8, $this, '__get', ['name' => $name], $this->initializere3f84) || 1) && $this->valueHolder85aa8 = $valueHolder85aa8;
if (isset(self::$publicPropertiese979b[$name])) {
return $this->valueHolder85aa8->$name;
}
$realInstanceReflection = new \ReflectionClass(get_parent_class($this));
if (! $realInstanceReflection->hasProperty($name)) {
$targetObject = $this->valueHolder85aa8;
$backtrace = debug_backtrace(false);
trigger_error(
sprintf(
'Undefined property: %s::$%s in %s on line %s',
get_parent_class($this),
$name,
$backtrace[0]['file'],
$backtrace[0]['line']
),
\E_USER_NOTICE
);
return $targetObject->$name;
return;
}
$targetObject = $this->valueHolder85aa8;
$accessor = function & () use ($targetObject, $name) {
return $targetObject->$name;
};
$backtrace = debug_backtrace(true);
$scopeObject = isset($backtrace[1]['object']) ? $backtrace[1]['object'] : new \ProxyManager\Stub\EmptyClassStub();
$accessor = $accessor->bindTo($scopeObject, get_class($scopeObject));
$returnValue = & $accessor();
return $returnValue;
}
public function __set($name, $value)
{
$this->initializere3f84 && ($this->initializere3f84->__invoke($valueHolder85aa8, $this, '__set', array('name' => $name, 'value' => $value), $this->initializere3f84) || 1) && $this->valueHolder85aa8 = $valueHolder85aa8;
$realInstanceReflection = new \ReflectionClass(get_parent_class($this));
if (! $realInstanceReflection->hasProperty($name)) {
$targetObject = $this->valueHolder85aa8;
return $targetObject->$name = $value;
return;
}
$targetObject = $this->valueHolder85aa8;
$accessor = function & () use ($targetObject, $name, $value) {
return $targetObject->$name = $value;
};
$backtrace = debug_backtrace(true);
$scopeObject = isset($backtrace[1]['object']) ? $backtrace[1]['object'] : new \ProxyManager\Stub\EmptyClassStub();
$accessor = $accessor->bindTo($scopeObject, get_class($scopeObject));
$returnValue = & $accessor();
return $returnValue;
}
public function __isset($name)
{
$this->initializere3f84 && ($this->initializere3f84->__invoke($valueHolder85aa8, $this, '__isset', array('name' => $name), $this->initializere3f84) || 1) && $this->valueHolder85aa8 = $valueHolder85aa8;
$realInstanceReflection = new \ReflectionClass(get_parent_class($this));
if (! $realInstanceReflection->hasProperty($name)) {
$targetObject = $this->valueHolder85aa8;
return isset($targetObject->$name);
return;
}
$targetObject = $this->valueHolder85aa8;
$accessor = function () use ($targetObject, $name) {
return isset($targetObject->$name);
};
$backtrace = debug_backtrace(true);
$scopeObject = isset($backtrace[1]['object']) ? $backtrace[1]['object'] : new \ProxyManager\Stub\EmptyClassStub();
$accessor = $accessor->bindTo($scopeObject, get_class($scopeObject));
$returnValue = $accessor();
return $returnValue;
}
public function __unset($name)
{
$this->initializere3f84 && ($this->initializere3f84->__invoke($valueHolder85aa8, $this, '__unset', array('name' => $name), $this->initializere3f84) || 1) && $this->valueHolder85aa8 = $valueHolder85aa8;
$realInstanceReflection = new \ReflectionClass(get_parent_class($this));
if (! $realInstanceReflection->hasProperty($name)) {
$targetObject = $this->valueHolder85aa8;
unset($targetObject->$name);
return;
}
$targetObject = $this->valueHolder85aa8;
$accessor = function () use ($targetObject, $name) {
unset($targetObject->$name);
};
$backtrace = debug_backtrace(true);
$scopeObject = isset($backtrace[1]['object']) ? $backtrace[1]['object'] : new \ProxyManager\Stub\EmptyClassStub();
$accessor = $accessor->bindTo($scopeObject, get_class($scopeObject));
$returnValue = $accessor();
return $returnValue;
}
public function __clone()
{
$this->initializere3f84 && ($this->initializere3f84->__invoke($valueHolder85aa8, $this, '__clone', array(), $this->initializere3f84) || 1) && $this->valueHolder85aa8 = $valueHolder85aa8;
$this->valueHolder85aa8 = clone $this->valueHolder85aa8;
}
public function __sleep()
{
$this->initializere3f84 && ($this->initializere3f84->__invoke($valueHolder85aa8, $this, '__sleep', array(), $this->initializere3f84) || 1) && $this->valueHolder85aa8 = $valueHolder85aa8;
return array('valueHolder85aa8');
}
public function __wakeup()
{
\Closure::bind(function (\cases\Sample $instance) {
unset($instance->value);
}, $this, 'cases\\Sample')->__invoke($this);
}
public function setProxyInitializer(\Closure $initializer = null)
{
$this->initializere3f84 = $initializer;
}
public function getProxyInitializer()
{
return $this->initializere3f84;
}
public function initializeProxy() : bool
{
return $this->initializere3f84 && ($this->initializere3f84->__invoke($valueHolder85aa8, $this, 'initializeProxy', array(), $this->initializere3f84) || 1) && $this->valueHolder85aa8 = $valueHolder85aa8;
}
public function isProxyInitialized() : bool
{
return null !== $this->valueHolder85aa8;
}
public function getWrappedValueHolderValue() : ?object
{
return $this->valueHolder85aa8;
}
}