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.
Installation:
composer require symfony/var-exporter
Ensure ext-deepclone is installed for optimal performance (fallback polyfill included).
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', ...]);`)
Where to Look First:
VarExporter::export() for serializationDeepCloner for cloningProxyHelper for lazy proxies// 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';
OPcache for faster execution than unserialize().$cloner = new DeepCloner($prototype); // Reuse for repeated clones
$clone = $cloner->clone();
unserialize(serialize()) due to copy-on-write for strings/arrays.$proxyCode = ProxyHelper::generateLazyProxy(new ReflectionClass(AbstractRepository::class));
eval('class AbstractRepositoryProxy ' . $proxyCode);
$proxy = AbstractRepositoryProxy::createLazyProxy(
initializer: fn() => new DatabaseRepository()
);
// $proxy->method() triggers initialization.
use Symfony\Component\VarExporter\VarExporter;
$model = User::find(1);
$exported = VarExporter::export($model);
// Store $exported in cache/database.
$container->extend('app.service', function ($service) {
return DeepCloner::deepClone($service); // Isolate service state.
});
$mockData = VarExporter::export([
'user' => new User(),
'roles' => ['ADMIN', 'EDITOR']
]);
// Use $mockData in tests.
Combine VarExporter with Laravel’s cache:
Cache::put('user.1', VarExporter::export($user), now()->addHour());
$user = Cache::get('user.1');
$proxyCode = ProxyHelper::generateLazyProxy(new ReflectionClass(Collection::class));
eval('class LazyCollection ' . $proxyCode);
$lazyCollection = LazyCollection::createLazyProxy(
initializer: fn() => User::all()
);
// Queries only when iterated.
$cloner = new DeepCloner();
$clone = $cloner->clone($original); // Preserves readonly state.
Class Not Found Exceptions:
VarExporter throws ClassNotFoundException for missing classes (unlike serialize()).Circular References:
DeepCloner with caution or limit depth:
$cloner = new DeepCloner();
$cloner->setMaxDepth(5); // Prevent infinite recursion.
Lazy Proxy Contravariance:
ProxyHelper with explicit type hints.Readonly Properties:
__unserialize() modifies readonly properties.symfony/var-exporter v8.0.8+ for fixes.OPcache Dependency:
Inspect Exported Code:
$exported = VarExporter::export($object, VarExporter::EXPORT_DEBUG);
// Debug mode adds comments for troubleshooting.
Validate Lazy Proxies:
if (!$proxy instanceof LazyProxyInterface) {
throw new \RuntimeException('Proxy not initialized.');
}
Check for Deprecated Methods:
VarExporter::EXPORT_DEPRECATED flag to log deprecated features.Custom Exporters:
Extend VarExporter for domain-specific serialization:
class CustomExporter extends VarExporter {
public static function export($value) {
return parent::export($value, self::EXPORT_DEBUG);
}
}
DeepCloner Callbacks:
$cloner = new DeepCloner();
$cloner->addCallback('App\Models\User', function ($user) {
return $user->load('posts'); // Custom logic.
});
Proxy Initializers:
$proxy = ProxyHelper::generateLazyProxy(new ReflectionClass(MyClass::class));
// Custom initializer with dependency injection.
PHP Version Compatibility:
ext-deepclone:
pecl install deepclone
PSR-2 Compliance:
VarExporter::export($value, VarExporter::EXPORT_NOT_PRETTY);
Reuse DeepCloner Instances:
$cloner = new DeepCloner(); // Reuse across clones.
Cache Exported Code:
$exported = VarExporter::export($object);
Cache::remember("export_{$object->id}", now()->addDay(), function () use ($object) {
return VarExporter::export($object);
});
Lazy Proxy Caching:
static $proxyCache = [];
if (!isset($proxyCache[$className])) {
$proxyCache[$className] = ProxyHelper::generateLazyProxy(new ReflectionClass($className));
}
How can I help you explore Laravel packages today?