anujrnair / php-json-marshaller
一个用于将 JSON 字符串序列化和反序列化到填充 PHP 类的库
Requires
- php: >=5.4.0
- doctrine/annotations: *
Requires (Dev)
- phpunit/phpunit: ~4.8.0
This package is auto-updated.
Last update: 2024-09-29 03:36:34 UTC
README
一个通过注解驱动的库,用于将 JSON 字符串序列化和反序列化到填充 PHP 类
我们希望对序列化和反序列化有更细粒度的控制,因为
- json_decode 总是返回一个 StdClass 对象。我们希望能够将解码结果放入我们的自定义类中。
- 我们可以添加我们接收/发送的数据的预期类型信息,并在使用之前进行验证。
- json_encode 无法按属性逐个控制。这将允许我们做到这一点。
最新版本可在此处找到: https://github.com/AnujRNair/php-json-marshaller。
安装
$ git clone https://github.com/AnujRNair/php-json-marshaller.git
$ composer install
使用
在您的类中,为您的属性和方法添加 MarshallProperty 注解,以描述 JSON 应该如何序列化或反序列化。
MarshallProperty 注解需要一个名称和类型,否则将抛出异常。
您可以在任何公共属性或方法上执行此操作。
use PhpJsonMarshaller\Annotations\MarshallProperty; class User { /** * @MarshallProperty(name="id", type="int") * This property is public - it will be accessed directly */ public $id; /** * This property is NOT public - it must be accessed through a getter (marshalling) or a setter (unmarshalling) */ protected $name; /** * @MarshallProperty(name="name", type="string") * This function will be used for marshalling json */ public function getName() { return $this->name; } /** * @MarshallProperty(name="name", type="string") * This function will be used for unmarshalling json */ public function setName($name) { $this->name = $name; } }
配置您的类后,加载 JSONMarshaller 类的一个实例,并调用 marshall 或 unmarshall 函数
use PhpJsonMarshaller\Decoder\ClassDecoder; use PhpJsonMarshaller\Marshaller\JsonMarshaller; use PhpJsonMarshaller\Reader\DoctrineAnnotationReader; $json = '{ "id": 12345, "name": "Anuj" }'; // Assuming autoloading $marshaller = new JsonMarshaller(new ClassDecoder(new DoctrineAnnotationReader())); // Notice the fully qualified namespace! $user = $marshaller->unmarshall($json, '\My\Example\User'); // Use the new class echo $user->getName(); // (string) 'Anuj' // Marshall the class $marshalled = $marshaller->marshall($user); // $json and $marshalled are both json_encoded string holding the same data $json == $marshalled;
现在 $user 变量应该是 \My\Example\User 类的实例,并用我们从 JSON 字符串中传递的 id 和 name 填充。
$marshalled 变量将是一个包含 \My\Example\User 对象实例数据的 json 编码字符串。
嵌套对象
您还可以在类内部嵌套类,以进行递归序列化和反序列化,如下所示
use PhpJsonMarshaller\Annotations\MarshallProperty; class User { /** * @MarshallProperty(name="address", type="\My\Example\Address") * Notice the fully qualified namespace! */ public $address; }
然后在您的代码中
use PhpJsonMarshaller\Decoder\ClassDecoder; use PhpJsonMarshaller\Marshaller\JsonMarshaller; use PhpJsonMarshaller\Reader\DoctrineAnnotationReader; $json = '{ "id": 12345, "name": "Anuj", "address": { "id": 1, "street": "123 Main Street" } }'; // Assuming autoloading $marshaller = new JsonMarshaller(new ClassDecoder(new DoctrineAnnotationReader())); // Notice the fully qualified namespace! $user = $marshaller->unmarshall($json, '\My\Example\User'); // Use the nested object $user->getAddress()->getStreet(); // (string) "123 Main Street"
对象数组
您可以通过在 MarshallProperty 注解的类型中指示来序列化和反序列化标量/对象的数组
use PhpJsonMarshaller\Annotations\MarshallProperty; class User { /** * @MarshallProperty(name="flags", type="\My\Example\Flag[]") * Notice the fully qualified namespace and the array indicator in the type */ public $flags; }
然后在您的代码中
use PhpJsonMarshaller\Decoder\ClassDecoder; use PhpJsonMarshaller\Marshaller\JsonMarshaller; use PhpJsonMarshaller\Reader\DoctrineAnnotationReader; $json = '{ "id": 12345, "name": "Anuj", "flags": [ { "id": 11087, "value": 0 }, { "id": 11088, "value": 1 } ], }'; // Assuming autoloading $marshaller = new JsonMarshaller(new ClassDecoder(new DoctrineAnnotationReader())); // Notice the fully qualified namespace! $user = $marshaller->unmarshall($json, '\My\Example\User'); // Use the data $user->getFlags()[0]->getId(); // (int) 11087
使用构造函数反序列化对象
要使用具有必需参数的构造函数反序列化对象,请使用 @MarshallCreator 注解来告诉序列化器使用哪些值来实例化类。
此注解接受一个 @MarshallProperty 对象数组,如下所示
use PhpJsonMarshaller\Annotations\MarshallCreator; use PhpJsonMarshaller\Annotations\MarshallProperty; class User { /** * @var int $id */ protected $id; /** * @var float $rank */ protected $rank; /** * @MarshallCreator({@MarshallProperty(name="id", type="int"), @MarshallProperty(name="rank", type="float")}) */ public function __construct($id, $rank) { $this->id = $id; $this->rank = $rank; } }
序列化器将在传递给它的 json 字符串中查找这些值(与类实例化的同一级别)并使用这些值实例化对象。
缓存
您可以通过缓存解码类来提高性能。这 不会 缓存来自 JSON 字符串的数据。
为此,实例化一个 Cache 类的实例,并传入一个存储类型。然后将其传递给 ClassDecoder 实例
use PhpJsonMarshaller\Cache\Cache; use PhpJsonMarshaller\Cache\Storage\InMemoryStorage; use PhpJsonMarshaller\Decoder\ClassDecoder; use PhpJsonMarshaller\Marshaller\JsonMarshaller; use PhpJsonMarshaller\Reader\DoctrineAnnotationReader; $marshaller = new JsonMarshaller( new ClassDecoder( new DoctrineAnnotationReader(), new Cache( new InMemoryStorage() ) ) );
请参阅 \PhpJsonMarshaller\Cache\Storage 以获取所有可用的存储类型。MemcachedStorage
也有一些您可以设置的选项。
未知条目
您可以通过添加 MarshallConfig 注解到特定的类来专门允许一个类在遇到任何未知 JSON 变量时失败
use PhpJsonMarshaller\Annotations\MarshallConfig; /** * @MarshallConfig(ignoreUnknown=false) */ class User { }
现在如果您尝试将一个未知变量反序列化到这个类中,将会抛出异常。
测试
测试由 PHPUnit 覆盖。浏览到库的根目录并运行 phpunit
。
请确保 memcached 守护进程正在运行以确保 MemcachedStorageTest
测试通过。
许可
请参阅 许可