jurjean/spray-serializer

此包最新版本(2.0.0)没有可用的许可信息。

2.0.0 2016-04-14 10:10 UTC

README

快速且易于使用 PHP 对象的序列化和反序列化。

Build Status

内部机制

序列化通过使用 Closure::bind 方法附加到特定的类作用域来执行。为了保持速度,反射仅在生成序列化代码时使用。

如何使用

让我们从一个要序列化的类开始。请注意,注释暗示了序列化器,并且它们是反序列化对象所必需的。

/**
 * Person
 */
class Person
{
    /**
     * @var string
     */
    private $name;

    /**
     * @var Address
     */
    private $address;

    public function __construct($name, Address $address)
    {
        $this->name = (string) $name;
        $this->address = $address;
    }
}

/**
 * Address
 */
class Address
{
    /**
     * @var string
     */
    private $street;

    public function __construct($street)
    {
        $this->street = (string) $street;
    }
}

然后我们初始化序列化器。

$serializer = new Serializer();
$serializer->attach(
    new ObjectListener(
        new SerializerLocator(
            new SerializerRegistry(),
            new ObjectSerializerGenerator(
                new AnnotationBackedPropertyInfo()
            ),
            new ArrayCache('Serializer')
        )
    )
);

现在我们可以将几乎任何对象序列化为数组,然后再将数组反序列化为对象。

$data = $serializer->serialize(new Person('Name', new Address('Street')));
var_dump($data);
// array(2) {
//   'name' =>
//   string(4) "Name"
//   'address' =>
//   array(1) {
//     'street' =>
//     string(6) "Street"
//   }
// }


$object = $serializer->deserialize('Person', $data);
var_dump($object);
// class Person#8 (2) {
//   private $name =>
//   string(4) "Name"
//   private $address =>
//   class Address#18 (1) {
//     private $street =>
//     string(6) "Street"
//   }
// }

支持的注释

如上例所示,序列化器使用默认的 docblock 注释来确定序列化策略。以下注释受支持

class SerializeMe
{
    /**
     * @var string
     */
    private $string;

    /**
     * @var int
     */
    private $int;

    /**
     * @var integer
     */
    private $integer;

    /**
     * @var bool
     */
    private $bool;

    /**
     * @var boolean
     */
    private $boolean;

    /**
     * @var float
     */
    private $float;

    /**
     * @var double
     */
    private $double;

    /**
     * @var array
     */
    private $array;

    /**
     * @var Object
     */
    private $object;

    /**
     * @var string[]
     */
    private $stringArray;

    /**
     * @var Object[]
     */
    private $objectArray;

    /**
     * @var array<string>
     */
    private $stringArrayJavaStyle;

    /**
     * @var array<Object>
     */
    private $objectArrayJavaStyle;
}

几乎任何对象

实现序列化方法有一些限制。例如,无法反序列化 DateTime(Immutable) 对象。因此,添加了专门的序列化器。您需要在应用程序引导时将这些添加到 SerializerRegistry 中,如下所示

$registry = new SerializerRegistry();
$registry->add(new DateTimeSerializer());
$registry->add(new DateTimeImmutableSerializer());
$registry->add(new StdClassSerializer());

$serializer = new Serializer();
$serializer->attach(
    new ObjectListener(
        new SerializerLocator(
            $registry,
            new ObjectSerializerGenerator(
                new AnnotationBackedPropertyInfo()
            ),
            new ArrayCache('Serializer')
        )
    )
);

继承支持

为了支持对象继承(反)序列化,仅仅注释是不够的。需要 ObjectTypeListener 来启用此功能

$serializer = new Serializer();
$serializer->attach(
    new ObjectTypeListener()
);
$serializer->attach(
    new ObjectListener(
        new SerializerLocator(
            new SerializerRegistry(),
            new ObjectSerializerGenerator(
                new AnnotationBackedPropertyInfo()
            ),
            new ArrayCache('Serializer')
        )
    )
);

注意:启用此功能会导致数据中包含 '__type' => 'ClassName'

加密支持

当您的应用程序需要加密时,您必须附加 EncryptionListener

$blockCipher = BlockCipher::factory('mcrypt', ['algo' => 'aes']);
$blockCipher->setKey('5eDCZRmyX8s7nbgV9f6pVrmRISdc5t8L');

$serializer = new Serializer();
$serializer->attach(
    new EncryptionListener(
        new EncryptorLocator(
            new EncryptorGenerator(new AnnotationBackedPropertyInfo()),
            new ArrayCache('Encryptor')
        ),
        $blockCipher
    )
);
$serializer->attach(
    new ObjectListener(
        new SerializerLocator(
            new SerializerRegistry(),
            new ObjectSerializerGenerator(
                new AnnotationBackedPropertyInfo()
            ),
            new ArrayCache('Serializer')
        )
    )
);

缓存方法

库提供了两种缓存方法:数组和文件。数组缓存主要用于测试/开发目的。但是,对于生产环境,您最好使用 FileCache。

实际上,文件缓存将生成的序列化代码写入普通的 PHP 文件以供以后使用(因此自动缓存在 op-code 缓存中)。

以下是初始化序列化器的文件缓存的方法

use Symfony\Component\Filesystem\Filesystem;

$serializer = new Serializer();
$serializer->attach(
    new ObjectListener(
        new SerializerLocator(
            new SerializerRegistry(),
            new ObjectSerializerGenerator(
                new AnnotationBackedPropertyInfo()
            ),
            new FileCache(new Filesystem(), '/path/to/cache/directory', 'Serializer')
        )
    )
);