Skip to content
Permalink
Browse files

Merge pull request #645 from bbaga/master

Adding support for proxy class generation on container compilations
  • Loading branch information...
mnapoli committed Feb 28, 2019
2 parents 516caff + ee0a72d commit f16f27b7bc0876c7e76f568e0733d59997c8ec9c
@@ -140,3 +140,17 @@ $containerBuilder->writeProxiesToFile(true, __DIR__ . '/tmp/proxies');
```

You will need to clear the directory every time you deploy to avoid keeping outdated proxies.

### Generating proxy classes when compiling the container

By default proxies are written to disk the first time they are used.

Proxy classes can be pre-generated (for example before deploying) by enabling [container compilation](performances.md):

```php
// Enable writing proxies to file in the var/cache directory at container compile time
$containerBuilder->enableCompilation(__DIR__ . '/var/cache');
$containerBuilder->writeProxiesToFile(true, __DIR__ . '/var/cache');
```

For this functionality to work, both configuration options have to be set.
@@ -16,6 +16,7 @@
use DI\Definition\StringDefinition;
use DI\Definition\ValueDefinition;
use DI\DependencyException;
use DI\Proxy\ProxyFactory;
use InvalidArgumentException;
use PhpParser\Node\Expr\Closure;
use SuperClosure\Analyzer\AstAnalyzer;
@@ -64,6 +65,21 @@ class Compiler
*/
private $autowiringEnabled;
/**
* @var ProxyFactory
*/
private $proxyFactory;
public function __construct(ProxyFactory $proxyFactory)
{
$this->proxyFactory = $proxyFactory;
}
public function getProxyFactory() : ProxyFactory
{
return $this->proxyFactory;
}
/**
* Compile the container.
*
@@ -137,6 +137,8 @@ private function compileLazyDefinition(ObjectDefinition $definition) : string
$subDefinition->setLazy(false);
$subDefinition = $this->compiler->compileValue($subDefinition);
$this->compiler->getProxyFactory()->generateProxyClass($definition->getClassName());
return <<<PHP
\$object = \$this->proxyFactory->createProxy(
'{$definition->getClassName()}',
@@ -158,14 +158,17 @@ public function build()
$source = new SourceCache($source);
}
$proxyFactory = new ProxyFactory($this->writeProxiesToFile, $this->proxyDirectory);
$proxyFactory = new ProxyFactory(
$this->writeProxiesToFile,
$this->proxyDirectory
);
$this->locked = true;
$containerClass = $this->containerClass;
if ($this->compileToDirectory) {
$compiler = new Compiler;
$compiler = new Compiler($proxyFactory);
$compiledContainerFile = $compiler->compile(
$source,
$this->compileToDirectory,
@@ -60,6 +60,21 @@ public function createProxy(string $className, \Closure $initializer) : LazyLoad
return $this->proxyManager->createProxy($className, $initializer);
}
/**
* Generates and writes the proxy class to file.
*
* @param string $className name of the class to be proxied
*/
public function generateProxyClass(string $className)
{
// If proxy classes a written to file then we pre-generate the class
// If they are not written to file then there is no point to do this
if ($this->writeProxiesToFile) {
$this->createProxyManager();
$this->createProxy($className, function () {});
}
}
private function createProxyManager()
{
if ($this->proxyManager !== null) {
@@ -157,6 +157,25 @@ public function the_compiled_container_can_extend_a_custom_class()
self::assertInstanceOf(CompiledContainerTest\CustomParentContainer::class, $container);
}
/**
* @test
*/
public function proxy_classes_can_be_pregenerated_at_compile_time()
{
$builder = new ContainerBuilder;
$builder->enableCompilation(self::COMPILATION_DIR, self::generateCompiledClassName());
$builder->writeProxiesToFile(true, self::COMPILATION_DIR);
$builder->addDefinitions([
'foo' => create(\stdClass::class)->lazy(),
'bar' => autowire(CompiledContainerTest\ConstructorWithAbstractClassTypehint::class)->lazy(),
]);
$builder->build();
$countProxyClasses = count(glob(self::COMPILATION_DIR . '/ProxyManagerGeneratedProxy*'));
$this->assertEquals(2, $countProxyClasses);
}
/**
* @test
* @see https://github.com/PHP-DI/PHP-DI/issues/565

0 comments on commit f16f27b

Please sign in to comment.
You can’t perform that action at this time.