zumba / json-serializer
将PHP变量序列化为JSON格式,包括对象。同时也支持反序列化。
Requires
- php: ^7.0 || ^8.0
- ext-mbstring: *
Requires (Dev)
- phpunit/phpunit: >=6.0 <11.0
Suggests
- opis/closure: Allow to serialize PHP closures
README
这是一个用于将PHP变量序列化为JSON格式的库。它与PHP中的serialize()
函数类似,但输出是一个JSON编码的字符串。您还可以使用此工具生成的JSON进行反序列化,并恢复您的PHP内容。
支持的功能
- 标量、null、数组的编码/解码
- 对象的编码/解码
- 二进制数据的编码/解码
- 支持嵌套序列化
- 支持原始类定义中未声明的属性(即,在
stdClass
中的属性) - 支持对象递归
- 闭包(通过第三方库。见下文详细说明)
不支持序列化内容
- 资源(例如,
fopen()
响应) - NAN、INF常量
限制
- 包含空字节(\u0000)作为数组键的二进制数据无法正确解码,因为json扩展存在bug
此项目不应与PHP 5.4中添加的JsonSerializable
接口混淆。此接口用于json_encode
来编码对象。此接口没有反序列化,与本项目不同。
Json Serializer需要PHP >= 7.0,并已测试到PHP 8.2
示例
class MyCustomClass { public $isItAwesome = true; protected $nice = 'very!'; } $instance = new MyCustomClass(); $serializer = new Zumba\JsonSerializer\JsonSerializer(); $json = $serializer->serialize($instance); // $json will contain the content {"@type":"MyCustomClass","isItAwesome":true,"nice":"very!"} $restoredInstance = $serializer->unserialize($json); // $restoredInstance will be an instance of MyCustomClass
如何安装
如果您使用composer,请安装包zumba/json-serializer
。
$ composer require zumba/json-serializer
或者在您的composer.json
文件中直接添加zumba/json-serializer
。
如果您没有使用composer,您可以直接将项目中的src
文件夹中的文件复制到您的项目中。
序列化二进制字符串
二进制字符串在最终的JSON中引入了两个特殊标识符:@utf8encoded
和@scalar
。@utf8encoded
是从原始数据中具有其值(或键本身)从8位编码到UTF-8的键的数组。这是序列化器知道在反序列化时如何从UTF-8编码回8位的方法。示例
$data = ['key' => '<binaryvalue>', 'anotherkey' => 'nonbinaryvalue']; $serializer = new Zumba\JsonSerializer\JsonSerializer(); $json = $serializer->serialize($data); // $json will contain the content {"key":"<utf8encodedbinaryvalue>","anotherkey":"nonbinaryvalue","@utf8encoded":{"key":1}}
@scalar
仅用于要编码的值不是数组或对象,而是二进制字符串时。示例
$data = '<binaryvalue>'; $serializer = new Zumba\JsonSerializer\JsonSerializer(); $json = $serializer->serialize($data); // $json will contain the content {"@scalar":"<utf8encodedbinaryvalue>","@utf8encoded":1}
序列化闭包
对于序列化PHP闭包,您可以使用OpisClosure(首选)或SuperClosure(该项目已废弃,因此保留在此处以实现向后兼容)。
闭包序列化有一些限制。请检查OpisClosure或SuperClosure项目,以查看它们是否满足您的需求。
要使用OpisClosure与JsonSerializer一起使用,只需将其添加到闭包序列化器列表中。示例
$toBeSerialized = [ 'data' => [1, 2, 3], 'worker' => function ($data) { $double = []; foreach ($data as $i => $number) { $double[$i] = $number * 2; } return $double; } ]; $jsonSerializer = new \Zumba\JsonSerializer\JsonSerializer(); $jsonSerializer->addClosureSerializer(new \Zumba\JsonSerializer\ClosureSerializer\OpisClosureSerializer()); $serialized = $jsonSerializer->serialize($toBeSerialized);
如果您正在从SuperClosure迁移到OpisClosure(例如),则可以加载多个闭包序列化器。
PS:JsonSerializer不强制依赖于OpisClosure或SuperClosure。如果您想使用这两个项目,请确保在composer需求中添加它们,并使用addClosureSerializer()
方法加载它们。
自定义序列化器
某些类可能不适合使用默认的反射方法进行序列化和反序列化。
自定义序列化器提供了为特定类定义serialize
和unserialize
方法的能力。
class MyType { public $field1; public $field2; } class MyTypeSerializer { public function serialize(MyType $obj) { return array('fields' => $obj->field1 . ' ' . $obj->field2); } public function unserialize($values) { list($field1, $field2) = explode(' ', $values['fields']); $obj = new MyType(); $obj->field1 = $field1; $obj->field2 = $field2; return $obj; } } // map of "class name" => Custom serializer $customObjectSerializers['MyType'] = new MyTypeSerializer(); $jsonSerializer = new Zumba\JsonSerializer\JsonSerializer(null, $customObjectSerializers); $toBeSerialized = new MyType(); $toBeSerialized->field1 = 'x'; $toBeSerialized->field2 = 'y'; $json = $jsonSerializer->serialize($toBeSerialized); // $json == {"@type":"Zumba\\\\JsonSerializer\\\\Test\\\\SupportClasses\\\\MyType","fields":"x y"} $myType = $jsonSerializer->unserialize($json); // $myType == $toBeSerialized