prewk/seriplating

该包最新版本(0.6.2)没有可用的许可证信息。

序列化模板

0.6.2 2015-05-22 13:48 UTC

README

如果你不知道这个做什么,你可能不需要它,也不应该使用它。 :)

注意:这个库会安装Laravel,如果你不使用Laravel,这会很疯狂。它使用数组和平数辅助类。我目前在Laravel中使用它,所以对我来说这是合理的,即使这可能对你来说并不合理。抱歉。

首先,大量准备工作

<?php
use Prewk\Seriplating\GenericDeserializer;
use Prewk\Seriplating\GenericSerializer;
use Prewk\Seriplating\IdFactory;
use Prewk\Seriplating\IdResolver;
use Prewk\Seriplating\HierarchicalTemplate;
use Prewk\SeriplatingTemplate;
use Prewk\Seriplating\Seriplater;
use Prewk\Seriplating\Rule;

// Boilerplate classes
$t = new Seriplater(new Rule);
$idFactory = new IdFactory;
$idResolver = new IdResolver;
$genericSerializer = new GenericSerializer($idFactory);
$genericDeserializer = new GenericDeserializer($idResolver);
$hierarchy = new HierarchicalTemplate($idResolver);

// Bring your own repositories, implement Prewk\Seriplating\Contracts\RepositoryInterface
$fooRepository = new FooRepository;
$barRepository = new BarRepository;
$bazRepository = new BazRepository;

// A Foo entity has two Bars and a Baz
// Corresponding database tables could be foos, bars, and bazes

// Construct the serialization templates
// ..for Foo
$fooSeriplater = new GenericSerializer($genericSerializer, $genericDeserializer, fooRepository, [
    "id" => $t->id("foos"),
    "setting" => $t->value(),
    "bars" => $t->hasMany("bars"),
]);

// ..for Bar
$barSeriplater = new GenericSerializer($genericSerializer, $genericDeserializer, barRepository, [
    "id" => $t->id("bars"),
    "sort_order" => $t->increments(),
    "baz_id" => $t->references("bazes"),
]);

// ..for Baz
$bazSeriplater = new GenericSerializer($genericSerializer, $genericDeserializer, bazRepository, [
    "id" => $t->id("bazes"),
    "content" => $t->value(),
]);

// Register them in the hierarchical templating class
$hierarchy
    ->register($fooSeriplater)
    ->register($barSeriplater)
    ->register($bazSeriplater);

然后,开始序列化

<?php

// Entity built up from your own database content
$entityWithChildren = [
    "id" => 1,
    "setting" => "some value",
    "bars" => [
        [
            "id" => 1,
            "sort_order" => 0,
            "baz_id" => 1,
        ],
        [
            "id" => 2,
            "sort_order" => 1,
            "baz_id" => 1,
        ],
    ],
    "bazes" => [
        [
            "id" => 1,
            "content" => "<p>Lorem ipsum<p>",
        ],
    ]
];

// Serialize
$serialization = $hierarchy->serialize("foos", $entityWithChildren);

$serialization 现在包含一个自引用数组格式,可以转换为XML/等。

再次反序列化它

// Deserialize
$deserialized = $hierarchy->deserialize("foos", $serialization);

// The appropriate provided repositories will now have been called and entities will be created in the db
$fooId = $deserialized["id"];

可用的模板规则

  • ->value() 一个值
  • optional()->value() 一个可选值
  • ->id($name) 主键,$name对应实体名称(建议:数据库表名称)
  • ->references($name) 字段引用另一个实体中的主键,该实体的名称为$name
  • ->optional()->references($name) 一个可选引用字段
  • ->references($name, $fallback) 如果引用实体无法解析,则回退到给定的值(通常是0)
  • ->conditions($field, [... conditions ...], $default) 根据给定字段的值有条件地选择规则,如果有其他情况未匹配,则可选回退规则$default
  • ->deep([ ... regexp-indexed rules ....]) 一个正则表达式到规则的数组,它将对给定字段进行匹配并应用规则,其余字段按原样包含(如->value())使用数组点表示法
  • ->hasMany($name) 该字段是一个包含子实体和它们在HierarchicalTemplate中注册的模板规则的实体数组
  • ->inherits($field) 值从模板层次结构上方字段$field继承
  • ->inherits($field1, $field2, ...) 回退,如果层次结构中的所有实体都需要从顶部继承一些id,但在第一次继承之后向下称为foo_id很有用
  • ->increments() 在层次结构反序列化中,父反序列化器将从0开始并在每个实体上向上计数
  • ->increments($start, $increment) 起始值(默认0),以及增量值(例如-1用于递减)

条件

<?php
$template = [
    "id" => $t->id("foos"),
    "type" => $t->value(),
    "refers_to_different_things_depending_on_type" => $t->conditions("type", [
        "Bar" => $t->references("bars"),
        "Baz" => $t->references("bazes"),
        "Qux" => $t->value(),
    ]),
];

深度

<?php
$entity = [
    "id" => 123,
    "data" => [
        "something" => [
            ["id" => 500, "stuff" => true], // something.0.id = 500
            ["id" => 600, "stuff" => true], // something.1.id = 600
            ["id" => 700, "stuff" => false], // something.2.id = 700
        ],
        "bar_id" => 5,
    ],
];

$template = [
    "id" => $t->id("foos"),
    "data" => $t->deep([
        "/\\.something\\.\d+.id$/" => $t->references("something"),
        "/^bar_id$/" => $t->inherits("id"),
    ])
];

增量

<?php
$template1 = [
    "id" => $t->id("foos"),
    "bars" => $t->hasMany("bars"),
];
$template2 = [
    "id" => $t->id("bars"),
    "foo_id" => $t->references("foos"),
    "sort_order" => $t->increments(),
];

格式化器

<?php
use Prewk\Seriplating\Formatters\XmlFormatter;

$serialization = ...

$xmlFormatter = new XmlFormatter;

file_put_contents("serialized.xml", $xmlFormatter->formatSerialized($serialization));

$serialization = $xmlFormatter->unformatSerialized(file_get_contents("serialized.xml"));

已知问题

  • 自引用嵌套存在错误,应避免,而不是将相同类型的实体作为自己的树形结构排列,应将它们保持在具有正确引用的平面数组中
  • 条件继承、增量、hasMany可能存在错误
  • 代码目前完全是意大利面风格