haskel/map-serializer

基于map的对象序列化器

v0.1.2 2020-10-17 10:37 UTC

This package is auto-updated.

Last update: 2024-09-17 19:04:36 UTC


README

使用不同的小型简单模式来序列化你的对象和其他结构体



Latest Stable Version License

安装

composer require haskel/map-serializer

示例

/** Define a class that you want to serialize */
class User 
{
    private $id;
    private $name;
    private status = 0;
    private $role;
    private $phone;
    private $mail;
    private group;
    
    public function __construct($id, $name, $role)
    {
        $this->id = $id;
        $this->name = $name;
        $this->role = $role;
    }
    
    /**
     * ... Boring code with getters and setters ...
     */
}

/** Specify the schema */
$schema = [
    'id'     => 'int',
    'name'   => 'string',
    'status' => 'int',
    'role'   => 'string',
];
/** Add this schema definition, uniq schema name and class name to serializer */
$serializer->addSchema(User::class, 'default', $schema);

/** serialize some instance of the class */
$result = $serializer->serialize(new User('Alice', 'user'));
{
  id: 1,
  name: 'Alice',
  status: 0,
  role: 'user'
}

用法

基本用法

为特定类注册不同的模式。使用serialize()方法的第二个参数来指定一个模式。

use Haskel\MapSerializer\Serializer;

$serializer = new Serializer();

$schemas = [
    'default' => [
        'id'     => 'int',
        'name'   => 'string',
        'status' => 'int',
        'role'   => 'string',
    ],
    'short' => [
        'id'   => 'int',
        'name' => 'string',
    ]
];
foreach ($orderSchemas as $schemaName => $schema) {
    $serializer->addSchema(User::class, $schemaName, $schema);
}

$users = [
    new User(1, 'Alice'),
    new User(2, 'Bob'),
];
$result = $serializer->serialize($users, 'short');
[
  {
    id: 1,
    name: 'Alice'
  },
  {
    id: 2,
    name: 'Bob'
  }
]

嵌套对象

  1. 添加带名称的模式
  2. 使用此名称来嵌套一个对象
use Haskel\MapSerializer\Serializer;

$serializer = new Serializer();

$userSchema = [
    'id'     => 'int',
    'name'   => 'string',
    'group'  => 'short',
];
$groupSchema = [
  'id'   => 'int',
  'name' => 'string',
];
$serializer->addSchema(User::class, 'default', $userSchema);
$serializer->addSchema(Group::class, 'short', $groupSchema);

$group = new Group('sales');
$user = new User('Alice');
$user->addToGroup($group);

$result = $serializer->serialize($user);
{
  id: 1,
  name: 'Alice',
  group: {
    id: 1,
    name: 'sales'
  }
}



以您真正希望的方式格式化您的对象

格式化器是一个定义特定转换规则的对象。格式化器应该实现Haskel\MapSerializer\Formatter接口

看看这个例子

interface Formatter
{
    public function format($value, $schemaName);
}

class DatetimeFormatter implements Formatter
{
    public function format($value, $schemaName)
    {
        if (!$value instanceof DateTime) {
            throw new FormatterException(sprintf('wrong value type'));
        }

        switch ($schemaName) {
            case 'default':
            case 'datetime':
            default:
                return $value->format("Y-m-d H:i:s");

            case 'date':
                return $value->format('Y-m-d');

            case 'time':
                return $value->format('H:i:s');
        }
    }
}

它的工作原理

use Haskel\MapSerializer\Formatter\DatetimeFormatter;
use Haskel\MapSerializer\Serializer;

$serializer = new Serializer();
$serializer->addFormatter(new DatetimeFormatter());

$datetime = new DateTime('2015-10-21 12:00:00');
$serializer->format($datetime, 'date');
'2015-10-21'

如何加速提取

提取器是自动生成的类,可以帮助您从某个类的对象中提取字段。
ExtractorGenerator生成可以快速提取字段而不使用反射且不分析类结构的类。它看起来像这样

final class AppEntityUserExtractor extends \Haskel\MapSerializer\EntityExtractor\BaseExtractor
{
    /** @var \App\Entity\User */
    protected $entity;

    protected function extract()
    {
        return [
            "id" => $this->entity->getId(),
            "name" => $this->entity->getName(),
        ];
    }
    
    public function exists($fieldName)
    {
        if (count($this->fields) === 0) {
            $this->fields = $this->extract();
        }

        return array_key_exists($fieldName, $this->fields);
    }

    /**
     * @param $fieldName
     *
     * @return mixed
     */
    public function get($fieldName)
    {
        if (count($this->fields) === 0) {
            $this->fields = $this->extract();
        }

        return $this->fields[$fieldName];
    }
}

提取是自动进行的,但如果你想指定自己的提取器,那就很容易。只需实现一个接口\Haskel\MapSerializer\EntityExtractor\Extractor

namespace Haskel\MapSerializer\EntityExtractor;

interface Extractor
{
    public function get($fieldName);
    public function exists($fieldName);
}

class UserExtractor implements Extractor 
{
    public function get($fieldName)
    {
        return 42;
    }
    
    public function exists($fieldName)
    {
        return true;
    }
}

并将其注册到您的序列化器中的特定方案

$schema = [
    'id'     => 'int',
    'name'   => 'string',
    'status' => 'int',
    'role'   => 'string',
];
$serializer->addSchema(User::class, 'default', $schema);
$serializer->addExtractor(User::class, 'default', UserExtractor::class);
$result = $serializer->serialize(new User('Alice'));
{
  id: 42,
  name: '42',
  status: 42,
  role: '42'
}