prewk/seriquent

Eloquent 匿名(反)序列化

0.6.8 2016-10-27 13:56 UTC

README

  1. 序列化 Eloquent 模型的树状结构到包含匿名主键的自引用数组
  2. 反序列化 它回到数据库,并使用新的主键

安装

composer require prewk/seriquent

示例

您的数据库有一个名为 foos 的表,属于 qux 表。

foosbars 表有一个一对一的关系。

barsqux 都与 bazs 表有一个多态的一对多关系(它们是 "bazable")。

数据库内容

                ╔═══════╗    ╔═══════╗
             +--║ Foo 5 ║----║ Qux 2 ║
             |  ╚═══════╝    ╚═══════╝
             |                   |
             |                   |
    /--------+--------\          |
╔═══════╗╔═══════╗╔═══════╗      |
║ Bar 2 ║║ Bar 3 ║║ Bar 4 ║      |
╚═══════╝╚═══════╝╚═══════╝      |
    |        |                   |
    |        |                   |
╔═══════╗╔═══════╗           ╔═══════╗
║ Baz 5 ║║ Baz 6 ║           ║ Baz 7 ║
╚═══════╝╚═══════╝           ╚═══════╝

╔═════════════════════╗
║ foos                ║
╟─────────────────────╢
║ id: 5               ║
║ qux_id: 2           ║
║ name: "Lorem ipsum" ║
╚═════════════════════╝
╔═══════════╗╔═══════════╗╔═══════════╗
║ bars      ║║ bars      ║║ bars      ║
╟───────────╢╟───────────╢╟───────────╢
║ id: 2     ║║ id: 3     ║║ id: 4     ║
║ foo_id: 5 ║║ foo_id: 5 ║║ foo_id: 5 ║
╚═══════════╝╚═══════════╝╚═══════════╝
╔═══════════════════════╗
║ quxes                 ║
╟───────────────────────╢
║ id: 2                 ║
║ data: ["a", "b", "c"] ║
╚═══════════════════════╝
╔═════════════════╗╔═════════════════╗╔═════════════════╗
║ bazs            ║║ bazs            ║║ bazs            ║
╟─────────────────╢╟─────────────────╢╟─────────────────╢
║ id: 5           ║║ id: 6           ║║ id: 7           ║
║ bazable_type: 5 ║║ bazable_type: 5 ║║ bazable_type: 5 ║
║ bazable_id: 5   ║║ bazable_id: 5   ║║ bazable_id: 5   ║
╚═════════════════╝╚═════════════════╝╚═════════════════╝


期望的结果

{
    "Foo": [
        { "@id": "@1", "qux": "@7", "name": "Lorem ipsum" }
    ],
    "Bar": [
        { "@id": "@2", "foo": "@1" },
        { "@id": "@4", "foo": "@1" },
        { "@id": "@6", "foo": "@1" }
    ],
    "Baz": [
        { "@id": "@3", "bazable": ["Bar", "@2"] },
        { "@id": "@5", "bazable": ["Bar", "@4"] },
        { "@id": "@8", "bazable": ["Qux", "@7"] }
    ],
    "Qux": [
        { "@id": "@7", "data": ["a", "b", "c"] }
    ]
}
  • FooBar 等是 Eloquent 模型的全限定名
  • 所有实体都获得一个唯一的内部 ID "@id": "@123"
  • 实体通过其内部 ID 和关系名称引用另一个实体 "foo": "@1"
  • 常规列只是值 "name": "Lorem ipsum"

Eloquent 模型和序列化蓝图

<?php
use Illuminate\Database\Eloquent\Model;

class Foo extends Model {
    public static function getBlueprint() {
         return ["name", "bars", "qux"];
    }
    public function bars() { return $this->hasMany("Bar"); }
    public function qux() { return $this->belongsTo("Qux"); }
}

class Bar extends Model {
    public static function getBlueprint() {
         return ["foo", "bazs"];
    }
    public function foo() { return $this->belongsTo("Foo"); }
    public function bazs() { return $this->morphMany("Baz", "bazable"); }
}

class Baz extends Model {
    public static function getBlueprint() {
         return ["bazable"];
    }
    public function bazable() { return $this->morphTo(); }
}

class Qux extends Model {
    protected $casts = ["data" => "json"];
    public static function getBlueprint() {
         return ["foo", "bazs", "data"];
    }
    public function foo() { return $this->hasOne("Foo"); }
    public function bazs() { return $this->morphMany("Baz", "bazable"); }
}

使用静态 getBlueprint 方法返回字符串数组来描述一个模型的 字段关系,以进行序列化和反序列化。

这些字符串是列名或关系名。主键将自动获取。

用法

<?php
use Prewk\Seriquent;

// The factory helper method
$seriquent = Seriquent::make();

// Deserialize from Foo with id 5
$serialization = $seriquent->serialize(Foo::findOrFail(5));

// Save to disk
file_put_contents("serialization.json", json_encode($serialization));

// Load from disk
$serialization = json_decode(file_get_contents("serialization.json"), true);

// Deserialize into database
$results = $seriquent->deserialize($serialization);

// $results is an <internal @id> => <database id> associative array

许可证

MIT