nilportugues/serializer

序列化PHP变量,包括对象,支持任何格式。也支持反序列化。

1.2.1 2018-07-19 14:33 UTC

This package is not auto-updated.

Last update: 2024-09-14 17:21:30 UTC


README

Build Status Scrutinizer Code Quality SensioLabsInsight Latest Stable Version Total Downloads License Donate

安装

使用Composer安装此包

$ composer require nilportugues/serializer

简介

什么是序列化?

在数据存储的上下文中,序列化是将数据结构或对象状态转换为可以存储(例如,在文件或内存缓冲区中,或在网络连接链路上传输)并稍后可以在相同或另一台计算机环境中重建的格式的过程。

为什么不是serialize()unserialize()

这些原生函数依赖于在运行时加载和可用序列化的类,并将反序列化过程绑定到PHP平台。

如果序列化字符串包含对无法实例化的类的引用(例如,类已重命名、移动命名空间、删除或更改为抽象),PHP将立即因致命错误而停止。

这是问题吗?是的,这是一个问题。序列化数据现在不可用

特性

  • 序列化为JSONXMLYAML格式。
  • 序列化提供的对象的精确副本
  • 所有对象属性,公共、受保护和私有属性都会被序列化。
  • 读取并序列化当前对象的所有属性以及所有继承的属性。
  • 处理如SplFixedArray或实现Traversable的类的内部类序列化。
  • 提供基本的数据转换器,用于将对象转换为不同的输出格式。
  • 可用于生产.
  • 可扩展的:轻松编写自己的Serializer格式或数据Transformers

序列化

为了让序列化器工作,您需要做的就是将PHP对象传递给序列化器,并传递一个实现其字符串表示的策略。

序列化器(JSON、XML、YAML)

示例

在以下示例中,一个$post对象被序列化为JSON。

代码

use NilPortugues\Serializer\Serializer;
use NilPortugues\Serializer\Strategy\JsonStrategy;

//Example object
$post = new Post(
  new PostId(9),
  'Hello World',
  'Your first post',
  new User(
      new UserId(1),
      'Post Author'
  ),
  [
      new Comment(
          new CommentId(1000),
          'Have no fear, sers, your king is safe.',
          new User(new UserId(2), 'Barristan Selmy'),
          [
              'created_at' => (new DateTime('2015/07/18 12:13:00'))->format('c'),
              'accepted_at' => (new DateTime('2015/07/19 00:00:00'))->format('c'),
          ]
      ),
  ]
);

//Serialization 
$serializer = new JsonSerializer();

$serializedObject = $serializer->serialize($post);

//Returns: true
var_dump($post == $serializer->unserialize($serializedObject));

echo $serializedObject;

在转换成输出格式之前,对象是一个包含所有必要数据的数组,可以使用unserialize方法重建。

输出

{
    "@type": "Acme\\\\Domain\\\\Dummy\\\\Post",
    "postId": {
        "@type": "Acme\\\\Domain\\\\Dummy\\\\ValueObject\\\\PostId",
        "postId": {
            "@scalar": "integer",
            "@value": 14
        }
    },
    "title": {
        "@scalar": "string",
        "@value": "Hello World"
    },
    "content": {
        "@scalar": "string",
        "@value": "Your first post"
    },
    "author": {
        "@type": "Acme\\\\Domain\\\\Dummy\\\\User",
        "userId": {
            "@type": "Acme\\\\Domain\\\\Dummy\\\\ValueObject\\\\UserId",
            "userId": {
                "@scalar": "integer",
                "@value": 1
            }
        },
        "name": {
            "@scalar": "string",
            "@value": "Post Author"
        }
    },
    "comments": {
        "@map": "array",
        "@value": [
            {
                "@type": "Acme\\\\Domain\\\\Dummy\\\\Comment",
                "commentId": {
                    "@type": "Acme\\\\Domain\\\\Dummy\\\\ValueObject\\\\CommentId",
                    "commentId": {
                        "@scalar": "integer",
                        "@value": 1000
                    }
                },
                "dates": {
                    "@map": "array",
                    "@value": {
                        "created_at": {
                            "@scalar": "string",
                            "@value": "2015-07-18T12:13:00+00:00"
                        },
                        "accepted_at": {
                            "@scalar": "string",
                            "@value": "2015-07-19T00:00:00+00:00"
                        }
                    }
                },
                "comment": {
                    "@scalar": "string",
                    "@value": "Have no fear, sers, your king is safe."
                },
                "user": {
                    "@type": "Acme\\\\Domain\\\\Dummy\\\\User",
                    "userId": {
                        "@type": "Acme\\\\Domain\\\\Dummy\\\\ValueObject\\\\UserId",
                        "userId": {
                            "@scalar": "integer",
                            "@value": 2
                        }
                    },
                    "name": {
                        "@scalar": "string",
                        "@value": "Barristan Selmy"
                    }
                }
            }
        ]
    }
}'

自定义序列化器

如果首选自定义序列化策略,应使用Serializer类。必须实现StrategyInterfaceCustomStrategy

用法如下

use NilPortugues\Serializer\Serializer;
use NilPortugues\Serializer\Strategy\CustomStrategy;

$serializer = new Serializer(new CustomStrategy());

echo $serializer->serialize($post);

数据转换

转换器类与Strategy类有很大不同,因为这些不能unserialize(),因为在转换过程中所有类引用都丢失了。

要获得转换而不是使用Serializer类的用法,则需要使用DeepCopySerializer

序列化库附带一组已定义的转换器,这些转换器实现了StrategyInterface。用法与之前一样简单,只需传递一个转换器作为$strategy

例如

//...same as before ...

$serializer = new DeepCopySerializer(new JsonTransformer());
echo $serializer->serialize($post);

以下是一些示例及其输出,给定$post对象作为要转换的数据。

数组转换器

array(
  'postId' => 9,
  'title' => 'Hello World',
  'content' => 'Your first post',
  'author' => array(
       'userId' => 1,
       'name' => 'Post Author',
   ),
  'comments' => array(
          0 => array(
           'commentId' => 1000,
           'dates' => array(
              'created_at' => '2015-07-18T12:13:00+02:00',
              'accepted_at' => '2015-07-19T00:00:00+02:00',
            ),
           'comment' => 'Have no fear, sers, your king is safe.',
           'user' => array(
             'userId' => 2,
             'name' => 'Barristan Selmy',
            ),
          ),
      ),
);

扁平数组转换器

array(
  'postId' => 9,
  'title' => 'Hello World',
  'content' => 'Your first post',
  'author.userId' => 1,
  'author.name' => 'Post Author',
  'comments.0.commentId' => 1000,
  'comments.0.dates.created_at' => '2015-07-18T12:13:00+02:00',
  'comments.0.dates.accepted_at' => '2015-07-19T00:00:00+02:00',
  'comments.0.comment' => 'Have no fear, sers, your king is safe.',
  'comments.0.user.userId' => 2,
  'comments.0.user.name' => 'Barristan Selmy',
);

XML转换器

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <postId type="integer">9</postId>
  <title type="string">Hello World</title>
  <content type="string">Your first post</content>
  <author>
    <userId type="integer">1</userId>
    <name type="string">Post Author</name>
  </author>
  <comments>
    <sequential-item>
      <commentId type="integer">1000</commentId>
      <dates>
        <created_at type="string">2015-07-18T12:13:00+02:00</created_at>
        <accepted_at type="string">2015-07-19T00:00:00+02:00</accepted_at>
      </dates>
      <comment type="string">Have no fear, sers, your king is safe.</comment>
      <user>
        <userId type="integer">2</userId>
        <name type="string">Barristan Selmy</name>
      </user>
    </sequential-item>
  </comments>
</data>

YAML转换器

title: 'Hello World'
content: 'Your first post'
author:
    userId: 1
    name: 'Post Author'
comments:
    - { commentId: 1000, dates: { created_at: '2015-07-18T12:13:00+02:00', accepted_at: '2015-07-19T00:00:00+02:00' }, comment: 'Have no fear, sers, your king is safe.', user: { userId: 2, name: 'Barristan Selmy' } }

JSON Transformer

JsonTransformer 有两种版本。对于对象到 JSON 的转换,应使用以下转换器

输出

{
    "postId": 9,
    "title": "Hello World",
    "content": "Your first post",
    "author": {
        "userId": 1,
        "name": "Post Author"
    },
    "comments": [
        {
            "commentId": 1000,
            "dates": {
                "created_at": "2015-07-18T13:34:55+02:00",
                "accepted_at": "2015-07-18T14:09:55+02:00"
            },
            "comment": "Have no fear, sers, your king is safe.",
            "user": {
                "userId": 2,
                "name": "Barristan Selmy"
            }
        }
    ]
}

如果您想要的输出是用于 API 消费,您可以查看 JsonTransformer 库,或者使用以下方式引入它

$ composer require nilportugues/json

JSend转换器

JSend Transformer 已经构建用于将数据转换为有效的 JSend 规范资源。

请查看 JSend Transformer 或使用以下方式下载

$ composer require nilportugues/jsend

JSON API转换器

JSON API Transformer 已经构建用于将数据转换为有效的 JSON API 规范资源。

请查看 JSON API Transformer 或使用以下方式下载

$ composer require nilportugues/json-api

HAL+JSON转换器

HAL+JSON Transformer 已经构建用于 HAL+JSON API 创建。给定一个对象和一系列映射,输出有效的 HAL+JSON 资源表示。

请查看 HAL+JSON API Transformer 或使用以下方式下载

$ composer require nilportugues/haljson

质量

要在命令行中运行 PHPUnit 测试,请转到测试目录并执行 phpunit

此库尝试遵守 PSR-2PSR-4

如果您注意到有遵守上的疏忽,请通过拉取请求发送补丁。

贡献

对该软件包的贡献始终受到欢迎!

  • 问题跟踪器 上报告您发现的任何错误或问题。
  • 您可以在软件包的 Git 仓库 中获取源代码。

作者

许可证

代码库采用 MIT 许可证。