symfony/var-exporter

允许将任何可序列化的PHP数据结构导出为纯PHP代码

v7.1.2 2024-06-28 08:00 UTC

This package is auto-updated.

Last update: 2024-09-01 07:04:16 UTC


README

VarExporter组件提供各种工具来处理对象的内部状态

  • VarExporter::export() 允许将任何可序列化的PHP数据结构导出为纯PHP代码。在此过程中,它保留了与PHP序列化机制相关的所有语义(__wakeup__sleepSerializable__serialize__unserialize);
  • Instantiator::instantiate() 创建一个对象并设置其属性,而不调用其构造函数或任何其他方法;
  • Hydrator::hydrate() 可以设置现有对象的属性;
  • Lazy*Trait 可以使一个类表现得像懒加载的幽灵或虚拟代理。

VarExporter::export()

使用 VarExporter::export() 代替 serialize()igbinary 的原因是性能:多亏了OPcache,生成的代码比使用 unserialize()igbinary_unserialize() 更快且更节省内存。

var_export() 不同,它适用于任何可序列化的PHP值。

它还提供了一些对 var_export()/serialize() 的改进

  • 输出与PSR-2兼容;
  • 输出可以重新缩进,而不会弄乱数据中的 \r\n
  • 缺失的类抛出 ClassNotFoundException 而不是被反序列化为 PHP_Incomplete_Class 对象;
  • 涉及 SplObjectStorageArrayObjectArrayIterator 实例的引用被保留;
  • Reflection*IteratorIteratorRecursiveIteratorIterator 类在序列化时抛出异常(它们的反序列化版本无论如何都是破损的,请参阅 https://bugs.php.net/76737)。

Instantiator和Hydrator

Instantiator::instantiate($class) 创建一个给定类的对象,而不调用其构造函数或任何其他方法。

Hydrator::hydrate() 设置现有对象的属性,包括私有和受保护的属性。例如

// Sets the public or protected $object->propertyName property
Hydrator::hydrate($object, ['propertyName' => $propertyValue]);

// Sets a private property defined on its parent Bar class:
Hydrator::hydrate($object, ["\0Bar\0privateBarProperty" => $propertyValue]);

// Alternative way to set the private $object->privateBarProperty property
Hydrator::hydrate($object, [], [
    Bar::class => ['privateBarProperty' => $propertyValue],
]);

Lazy*Trait

该组件提供两种懒加载模式:幽灵对象和虚拟代理(请参阅 https://martinfowler.com.cn/eaaCatalog/lazyLoad.html 以获取参考)。

幽灵对象仅与具体和非内部类一起使用。在通用情况下,它们与使用其初始化器中的工厂不兼容。

虚拟代理与具体、抽象或内部类一起使用。它们提供类似于实际对象的API,并将调用转发到它们。它们可能会引起身份问题,因为代理可能不被视为它们所代理的实际对象的等价物。

由于这个身份问题,当可能时应优先选择幽灵对象。由 ProxyHelper 类抛出的异常可以帮助决定何时可以使用或不能使用。

幽灵对象和虚拟代理都为LazyObjectInterface提供了实现,允许将它们重置到初始状态或在需要时强制初始化。请注意,重置幽灵对象会跳过其只读属性。您应该使用虚拟代理来重置只读属性。

LazyGhostTrait

通过在您的类中直接使用LazyGhostTrait或使用ProxyHelper::generateLazyGhost(),可以使其实例实现懒加载。这是通过创建空实例并在访问属性时计算其状态来实现的。

class FooLazyGhost extends Foo
{
    use LazyGhostTrait;
}

$foo = FooLazyGhost::createLazyGhost(initializer: function (Foo $instance): void {
    // [...] Use whatever heavy logic you need here
    // to compute the $dependencies of the $instance
    $instance->__construct(...$dependencies);
    // [...] Call setters, etc. if needed
});

// $foo is now a lazy-loading ghost object. The initializer will
// be called only when and if a *property* is accessed.

LazyProxyTrait

或者,可以使用LazyProxyTrait来创建虚拟代理。

$proxyCode = ProxyHelper::generateLazyProxy(new ReflectionClass(Foo::class));
// $proxyCode contains the reference to LazyProxyTrait
// and should be dumped into a file in production envs
eval('class FooLazyProxy'.$proxyCode);

$foo = FooLazyProxy::createLazyProxy(initializer: function (): Foo {
    // [...] Use whatever heavy logic you need here
    // to compute the $dependencies of the $instance
    $instance = new Foo(...$dependencies);
    // [...] Call setters, etc. if needed

    return $instance;
});
// $foo is now a lazy-loading virtual proxy object. The initializer will
// be called only when and if a *method* is called.

资源