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

Var Exporter Laravel Package

symfony/var-exporter

Exports serializable PHP values to fast, OPcache-friendly PHP code, preserving serialization semantics and references. Includes DeepCloner for efficient deep cloning and ProxyHelper to generate lazy-loading proxies; uses ext-deepclone (or polyfill) for speed.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require symfony/var-exporter
    

    Ensure ext-deepclone is installed for optimal performance (fallback polyfill included).

  2. First Use Case: Export a complex object to reusable PHP code:

    use Symfony\Component\VarExporter\VarExporter;
    
    $user = new User(['name' => 'John', 'roles' => ['ROLE_USER']]);
    $exported = VarExporter::export($user);
    // Outputs PSR-2 compliant PHP code (e.g., `return new User(['name' => 'John', ...]);`)
    
  3. Where to Look First:

    • Official Documentation
    • VarExporter::export() for serialization
    • DeepCloner for cloning
    • ProxyHelper for lazy proxies

Implementation Patterns

Core Workflows

1. Exporting Objects to PHP Code

  • Use Case: Cache object states (e.g., Eloquent models, DTOs) for later rehydration.
  • Pattern:
    // Cache a model's state
    $exported = VarExporter::export($model);
    file_put_contents('cache/model_export.php', '<?php return ' . $exported . ';');
    
    // Rehydrate later
    $model = include 'cache/model_export.php';
    
  • Optimization: Combine with OPcache for faster execution than unserialize().

2. Deep Cloning

  • Use Case: Clone complex objects (e.g., nested collections, entities) without memory overhead.
  • Pattern:
    $cloner = new DeepCloner($prototype); // Reuse for repeated clones
    $clone = $cloner->clone();
    
  • Performance: Faster than unserialize(serialize()) due to copy-on-write for strings/arrays.

3. Lazy-Loading Proxies

  • Use Case: Defer expensive object initialization (e.g., database queries, API calls).
  • Pattern:
    $proxyCode = ProxyHelper::generateLazyProxy(new ReflectionClass(AbstractRepository::class));
    eval('class AbstractRepositoryProxy ' . $proxyCode);
    
    $proxy = AbstractRepositoryProxy::createLazyProxy(
        initializer: fn() => new DatabaseRepository()
    );
    // $proxy->method() triggers initialization.
    

4. Integration with Laravel

  • Eloquent Models:
    use Symfony\Component\VarExporter\VarExporter;
    
    $model = User::find(1);
    $exported = VarExporter::export($model);
    // Store $exported in cache/database.
    
  • Service Containers:
    $container->extend('app.service', function ($service) {
        return DeepCloner::deepClone($service); // Isolate service state.
    });
    

5. Testing and Mocking

  • Use Case: Export test data or mock complex objects.
  • Pattern:
    $mockData = VarExporter::export([
        'user' => new User(),
        'roles' => ['ADMIN', 'EDITOR']
    ]);
    // Use $mockData in tests.
    

Advanced Patterns

Hybrid Serialization

Combine VarExporter with Laravel’s cache:

Cache::put('user.1', VarExporter::export($user), now()->addHour());
$user = Cache::get('user.1');

Lazy-Loading Collections

$proxyCode = ProxyHelper::generateLazyProxy(new ReflectionClass(Collection::class));
eval('class LazyCollection ' . $proxyCode);

$lazyCollection = LazyCollection::createLazyProxy(
    initializer: fn() => User::all()
);
// Queries only when iterated.

Readonly Property Handling

$cloner = new DeepCloner();
$clone = $cloner->clone($original); // Preserves readonly state.

Gotchas and Tips

Pitfalls

  1. Class Not Found Exceptions:

    • VarExporter throws ClassNotFoundException for missing classes (unlike serialize()).
    • Fix: Ensure all classes in exported data are autoloadable.
  2. Circular References:

    • Deep cloning/circular references may cause infinite loops.
    • Fix: Use DeepCloner with caution or limit depth:
      $cloner = new DeepCloner();
      $cloner->setMaxDepth(5); // Prevent infinite recursion.
      
  3. Lazy Proxy Contravariance:

    • Interfaces/abstract classes may fail with contravariance issues.
    • Fix: Use ProxyHelper with explicit type hints.
  4. Readonly Properties:

    • Hydration may fail if __unserialize() modifies readonly properties.
    • Fix: Update to symfony/var-exporter v8.0.8+ for fixes.
  5. OPcache Dependency:

    • Exported code relies on OPcache for performance.
    • Fix: Ensure OPcache is enabled in production.

Debugging Tips

  1. Inspect Exported Code:

    $exported = VarExporter::export($object, VarExporter::EXPORT_DEBUG);
    // Debug mode adds comments for troubleshooting.
    
  2. Validate Lazy Proxies:

    if (!$proxy instanceof LazyProxyInterface) {
        throw new \RuntimeException('Proxy not initialized.');
    }
    
  3. Check for Deprecated Methods:

    • Use VarExporter::EXPORT_DEPRECATED flag to log deprecated features.

Extension Points

  1. Custom Exporters: Extend VarExporter for domain-specific serialization:

    class CustomExporter extends VarExporter {
        public static function export($value) {
            return parent::export($value, self::EXPORT_DEBUG);
        }
    }
    
  2. DeepCloner Callbacks:

    $cloner = new DeepCloner();
    $cloner->addCallback('App\Models\User', function ($user) {
        return $user->load('posts'); // Custom logic.
    });
    
  3. Proxy Initializers:

    $proxy = ProxyHelper::generateLazyProxy(new ReflectionClass(MyClass::class));
    // Custom initializer with dependency injection.
    

Configuration Quirks

  1. PHP Version Compatibility:

    • PHP 8.4+ required for native lazy objects (fallback to decorator pattern otherwise).
  2. ext-deepclone:

    • Install via PECL or use the polyfill:
      pecl install deepclone
      
    • Fallback polyfill is slower but functional.
  3. PSR-2 Compliance:

    • Exported code is PSR-2 compliant by default. Disable with:
      VarExporter::export($value, VarExporter::EXPORT_NOT_PRETTY);
      

Performance Optimizations

  1. Reuse DeepCloner Instances:

    $cloner = new DeepCloner(); // Reuse across clones.
    
  2. Cache Exported Code:

    $exported = VarExporter::export($object);
    Cache::remember("export_{$object->id}", now()->addDay(), function () use ($object) {
        return VarExporter::export($object);
    });
    
  3. Lazy Proxy Caching:

    static $proxyCache = [];
    if (!isset($proxyCache[$className])) {
        $proxyCache[$className] = ProxyHelper::generateLazyProxy(new ReflectionClass($className));
    }
    
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata