trebel/schematic

方案:方案交换协议

1.0 2022-12-28 19:15 UTC

This package is not auto-updated.

Last update: 2024-09-20 02:07:15 UTC


README

这个库的目的是创建一个具有导出和导入XML功能的方案交换协议。

它是如何工作的

这个库帮助我们创建具有严格验证和定义结构的新数据类型。

数据类型

当前版本中,有4种数据类型:字段列表操作符方案。每个创建的对象都是不可变的,一旦创建,就不能更改。

数据类型:Trebel\Schematic\Field

字段是数据类型的最小单元,任何“字段”的值必须是基本数据类型,或者我们可以看到以下可以是一个操作符

namespace Example\Fields\User;

use Trebel\Schematic\Field;

class ID extends Field {
    function __construct($value) {
        parent::__construct($value);
    }

    public function validate($value): bool {
        return ctype_digit($value) && $value > 0;
    }
}

class Name extends Field {
    function __construct($value) {
        parent::__construct($value);
    }

    public function validate($value): bool {
        return is_string($value) && strlen($value) > 0 && strlen($value) < 255;
    }
}

数据类型:Trebel\Schematic\Schema

方案数据类型是类似对象的类型,每个方案可以包含字段、列表或其他方案数据类型。

namespace Example;

use Trebel\Schematic\Schema;

class Person extends Schema {
    function __construct(...$args){
        parent::__construct(...$args);
    }

    public static $schema = [
        'Example\Fields\User\ID',
        'Example\Fields\User\Name',
    ];
}

然后我们可以创建我们的第一个方案对象

$person = new Example\Person([
    new Example\UserId(1234),
    new Example\UserName('Jhone'),
])

echo $person->id . "\n"; // Ourput: "1234"
echo $person->id->innerItem() . "\n"; // Ourput: 1234 // absolute value

ID是每个方案数据类型的必填字段

数据类型:Trebel\Schematic\Collection (List)

集合为什么不是列表?因为列表在PHP中是保留字

列表类似于数组的数据类型,与方案相比,唯一的区别是列表只能处理一种类型,而方案可以处理任何类型。

namespace Example;

use Trebel\Schematic\Collection;

class Persons extends Collection {
    protected static $type = 'Example\Person'; // Required

    function __construct(...$arg) {
        parent::__construct(...$arg);
    }
}

// To use Lists

$persons = new Examples\Persons([
    new Persons( ... ),
    new Persons( ... )
])

数据类型:Trebel\Schematic\Operator

操作符是特殊类型,不是用来定义元素,而是用来修改它。

例如,假设我们有一个包含字段 IDPrice 的方案 Car,如果我们想在 Price 中增加或减少现有价格,我们可以在 Price 内创建一个 Increase 操作符

$carTwo = new Schemas\Car([
    new Fields\Car\ID(31),
    new Fields\Car\Price(
        new Operators\Increase(123),
    )
]);

在这个版本中,操作符仅适用于字段和列表数据类型。定义了以下操作符

推入 (Trebel\Schematic\Operators\Push),
拉出 (Trebel\Schematic\Operators\Pull)
适用于 列表 数据类型

增加 (Trebel\Schematic\Operators\Increase)
适用于 字段 数据类型

但您也可以创建自己的数据类型。

为了支持字段或列表上的任何操作符,您需要在该类型内定义所有操作符。

class Cars extends Collection {
    public static $type = 'Examples\Schemas\Car';
    public static $operators = [
        'Trebel\Schematic\Operators\Push',
        'Trebel\Schematic\Operators\Pull',
    ];

    function __construct(...$arg) {
        parent::__construct(...$arg);
    }
}
// Example
new Lists\Cars([
    new Operators\Push(
        new Schemas\Car([
            new Fields\Car\ID(33),
            new Fields\Car\Name('Ford'),
            new Fields\Car\Price(15000)
        ])
    ),
    // Pay attention that Pull operator can be not completed schema
    new Operators\Pull( new Schemas\Car([
        new Fields\Car\ID(31)]
    )),
])

导出/导入

库的主要部分是使用特定协议导出和导入XML方案的能力。

导出方案

$exporter = new Trebel\Schematic\Tools\Exporter($schema);
$exporter->export($pathToExport);

只能导入方案,不能导入字段、列表或操作符。

让我们看看一个具体的例子

$person = new Schemas\Person([
    new Fields\User\ID(15),
    new Lists\Cars([
        new Operators\Push(
            new Schemas\Car([
                new Fields\Car\ID(33),
                new Fields\Car\Name('Ford'),
                new Fields\Car\Price(15000)
            ])
        ),
        new Operators\Pull( new Schemas\Car([
            new Fields\Car\ID(31)]
        )),
    ])
])

$exporter = new Trebel\Schematic\Tools\Exporter($person);
$exporter->export('/tmp/example/index.xml');

输出xml文件可能是

文件:/tmp/example/index.xml

<?xml version="1.0" encoding="UTF-8"?>
<Content>
    <Person>
        <ID>15</ID>
        <Cars>
            <Push>
                <Car src="Car/33.xml"/>
            </Push>
            <Pull>
                <Car src="Car/31.xml"/>
            </Pull>
        </Cars>
    </Person>
</Content>

文件:/tmp/example/Car/33.xml

<?xml version="1.0" encoding="UTF-8"?>
<Content>
    <Car>
        <ID>33</ID>
        <Name>Ford</Name>
        <Price>15000</Price>
    </Car>
</Content>

同样适用于Car/31.xml

另一个例子

$car = new Schemas\Car([
    new Fields\Car\ID(31),
    new Fields\Car\Price(
        new Operators\Increase(500),
    )
]);

输出

<?xml version="1.0" encoding="UTF-8"?>
<Content>
    <Car>
        <ID>31</ID>
        <Price>
            <Increase>500</Increase>
        </Price>
    </Car>
</Content>

导入方案

$importer = new Trebel\Schematic\Tools\Importer([ .. list of supported schmeas]);
$schema = $importer->import($pathToSchema);

具体示例

$importer = new Tools\Importer([
    'Examples\Schemas\Car',
    'Examples\Schemas\Person',
    'Examples\Schemas\Toyota',
]);

$car = $importer->import('/tmp/car/index.xml');

结论

有关更多信息,请查看位于 examples 文件夹中的教程