symfony/proxy-manager-bridge
Symfony bridge for ProxyManager that generates virtual proxies and lazy-loading services. Integrates proxy creation with the Symfony DependencyInjection container to improve performance and enable on-demand instantiation of expensive services.
Installation:
composer require symfony/proxy-manager-bridge
Ensure proxy-manager/proxy-manager is also installed (required dependency).
First Use Case:
use Doctrine\ORM\EntityManagerInterface;
use ProxyManager\Factory\LazyLoadingValueHolderFactory;
use Symfony\Component\DependencyInjection\ContainerBuilder;
$container = new ContainerBuilder();
$container->register('user.repository', UserRepository::class)
->setFactory([LazyLoadingValueHolderFactory::class, 'createProxy'])
->setArguments([UserRepository::class, [$entityManager]]);
Where to Look First:
ProxyManager\Factory\LazyLoadingValueHolderFactory for lazy-loading proxies.ProxyManager\Configuration for custom proxy configurations.Lazy-Loading Doctrine Entities:
LazyLoadingValueHolderFactory to defer loading of related collections until accessed.$proxy = LazyLoadingValueHolderFactory::createProxy(
User::class,
[$entityManager],
function ($proxy, $method, $args) use ($entityManager) {
return $entityManager->getRepository(User::class)->find($proxy->getId());
}
);
Integration with Symfony Services:
services.yaml:
services:
App\Service\LazyUserService:
factory: ['@ProxyManager\Factory\LazyLoadingValueHolderFactory', 'createProxy']
arguments:
- App\Service\UserService
- ['@doctrine.orm.entity_manager']
Custom Proxy Logic:
ProxyManager\GeneratorStrategy\EvaluatingStrategy to add custom behavior (e.g., logging, caching).use ProxyManager\GeneratorStrategy\EvaluatingStrategy;
$strategy = new EvaluatingStrategy(
new \ProxyManager\GeneratorStrategy\EvaluatingStrategy\Evaluator\SimpleEvaluator(),
new \ProxyManager\GeneratorStrategy\EvaluatingStrategy\Evaluator\PhpEvaluator()
);
$proxy = $factory->createProxy(UserService::class, $strategy, [$entityManager]);
AOP-Style Interception:
ProxyManager\GeneratorStrategy\EvaluatingStrategy to intercept method calls (e.g., for logging or metrics).$proxy = $factory->createProxy(
UserService::class,
new class extends EvaluatingStrategy {
public function generate($className, $originalClassName, $proxyClassName, $proxyMethods) {
// Custom logic here (e.g., add logging to all methods)
}
},
[$entityManager]
);
doctrine/orm for transparent lazy-loading of associations.# config/packages/proxy_manager.yaml
proxy_manager:
cache_dir: '%kernel.cache_dir%/proxy_manager'
ProxyManager\Configuration to disable proxy generation in tests:
$config = new \ProxyManager\Configuration();
$config->setProxiesTargetDir(sys_get_temp_dir()); // Disable caching
$factory = new LazyLoadingValueHolderFactory($config);
Proxy Cache Invalidation:
php bin/console cache:clear
cache_dir/proxy_manager.Circular Dependencies:
ProxyManager\Configuration to limit recursion depth:
$config = new \ProxyManager\Configuration();
$config->setMaxRecursionDepth(5); // Default is 10
Serialization Issues:
__serialize()/__unserialize() manually.Debugging Proxies:
getProxyTarget() to inspect the original object:
if ($object instanceof \ProxyManager\Proxy\LazyLoadingInterface) {
$original = $object->getProxyTarget();
}
Performance Overhead:
ProxyManager\Configuration to optimize:
$config->setUseAutoloading(true); // Use autoloader for proxies (faster)
$config = new \ProxyManager\Configuration();
$config->setGeneratorStrategy(new \ProxyManager\GeneratorStrategy\EvaluatingStrategy(
new \ProxyManager\GeneratorStrategy\EvaluatingStrategy\Evaluator\SimpleEvaluator(),
new \ProxyManager\GeneratorStrategy\EvaluatingStrategy\Evaluator\PhpEvaluator(),
new \ProxyManager\GeneratorStrategy\EvaluatingStrategy\Logger\FileLogger('/tmp/proxy.log')
));
cache_dir/proxy_manager to verify logic.Custom Proxy Factories:
ProxyManager\Factory\AbstractFactory to create domain-specific proxies.class CustomProxyFactory extends AbstractFactory {
public function createProxy($className, $initializer = null, $initializerParameters = []) {
$config = new \ProxyManager\Configuration();
$config->setGeneratorStrategy(new CustomEvaluatingStrategy());
return parent::createProxy($className, $initializer, $initializerParameters, $config);
}
}
Dynamic Proxy Generation:
ProxyManager\Generator to generate proxies at runtime (e.g., for dynamic services):
$generator = new \ProxyManager\Generator();
$proxyClass = $generator->generateProxyClass(
UserService::class,
new CustomEvaluatingStrategy(),
$proxyMethods
);
Integration with Symfony Compiler Pass:
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ProxyCompilerPass implements CompilerPassInterface {
public function process(ContainerBuilder $container) {
$definition = $container->findDefinition('app.lazy_service');
$definition->setFactory([LazyLoadingValueHolderFactory::class, 'createProxy']);
}
}
Register the pass in services.yaml:
services:
_instanceof:
App\CompilerPass\ProxyCompilerPass:
tags: [compiler_pass]
How can I help you explore Laravel packages today?