Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Proxy Manager Bridge Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require symfony/proxy-manager-bridge
    

    Ensure proxy-manager/proxy-manager is also installed (required dependency).

  2. First Use Case:

    • Lazy-Loading Services: Use the bridge to generate proxies for Doctrine entities or services that need lazy initialization (e.g., expensive DB queries).
    • Example:
      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]]);
      
  3. Where to Look First:

    • Symfony Docs: ProxyManager Bridge (if available).
    • ProxyManager\Factory\LazyLoadingValueHolderFactory for lazy-loading proxies.
    • ProxyManager\Configuration for custom proxy configurations.

Implementation Patterns

Common Workflows

  1. Lazy-Loading Doctrine Entities:

    • Use LazyLoadingValueHolderFactory to defer loading of related collections until accessed.
    • Example:
      $proxy = LazyLoadingValueHolderFactory::createProxy(
          User::class,
          [$entityManager],
          function ($proxy, $method, $args) use ($entityManager) {
              return $entityManager->getRepository(User::class)->find($proxy->getId());
          }
      );
      
  2. Integration with Symfony Services:

    • Register proxies as services in services.yaml:
      services:
          App\Service\LazyUserService:
              factory: ['@ProxyManager\Factory\LazyLoadingValueHolderFactory', 'createProxy']
              arguments:
                  - App\Service\UserService
                  - ['@doctrine.orm.entity_manager']
      
  3. Custom Proxy Logic:

    • Extend ProxyManager\GeneratorStrategy\EvaluatingStrategy to add custom behavior (e.g., logging, caching).
    • Example:
      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]);
      
  4. AOP-Style Interception:

    • Use ProxyManager\GeneratorStrategy\EvaluatingStrategy to intercept method calls (e.g., for logging or metrics).
    • Example:
      $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]
      );
      

Integration Tips

  • Doctrine ORM: Combine with doctrine/orm for transparent lazy-loading of associations.
  • Symfony Cache: Cache generated proxies to avoid regeneration on every request.
    # config/packages/proxy_manager.yaml
    proxy_manager:
        cache_dir: '%kernel.cache_dir%/proxy_manager'
    
  • Testing: Use ProxyManager\Configuration to disable proxy generation in tests:
    $config = new \ProxyManager\Configuration();
    $config->setProxiesTargetDir(sys_get_temp_dir()); // Disable caching
    $factory = new LazyLoadingValueHolderFactory($config);
    

Gotchas and Tips

Pitfalls

  1. Proxy Cache Invalidation:

    • Generated proxies are cached. Clear the cache when updating proxy logic or dependencies:
      php bin/console cache:clear
      
    • For custom cache dirs, manually delete files in cache_dir/proxy_manager.
  2. Circular Dependencies:

    • ProxyManager may fail if proxies reference each other circularly. Use ProxyManager\Configuration to limit recursion depth:
      $config = new \ProxyManager\Configuration();
      $config->setMaxRecursionDepth(5); // Default is 10
      
  3. Serialization Issues:

    • Proxies may not serialize/deserialize correctly. Avoid serializing proxied objects or implement __serialize()/__unserialize() manually.
  4. Debugging Proxies:

    • Proxies appear as anonymous classes in stack traces. Use getProxyTarget() to inspect the original object:
      if ($object instanceof \ProxyManager\Proxy\LazyLoadingInterface) {
          $original = $object->getProxyTarget();
      }
      
  5. Performance Overhead:

    • Proxy generation adds overhead. Benchmark in production-like environments. Use ProxyManager\Configuration to optimize:
      $config->setUseAutoloading(true); // Use autoloader for proxies (faster)
      

Debugging Tips

  • Enable Proxy Logging:
    $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')
    ));
    
  • Check Generated Proxies:
    • Inspect generated proxy classes in cache_dir/proxy_manager to verify logic.
  • Symfony Debug Toolbar:
    • Use the "Proxies" panel (if available) to list active proxies and their targets.

Extension Points

  1. Custom Proxy Factories:

    • Extend ProxyManager\Factory\AbstractFactory to create domain-specific proxies.
    • Example:
      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);
          }
      }
      
  2. Dynamic Proxy Generation:

    • Use ProxyManager\Generator to generate proxies at runtime (e.g., for dynamic services):
      $generator = new \ProxyManager\Generator();
      $proxyClass = $generator->generateProxyClass(
          UserService::class,
          new CustomEvaluatingStrategy(),
          $proxyMethods
      );
      
  3. Integration with Symfony Compiler Pass:

    • Register proxies during container compilation for better performance:
      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]
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor