earc/cast

eArc - 显式架构框架 - cast 组件

1.1 2021-05-02 17:55 UTC

This package is auto-updated.

Last update: 2024-09-29 05:29:19 UTC


README

earc/cast 是一个轻量级无依赖的扁平数据映射器,可以将由对象/数组表示的数据映射到其他对象/数组上。因此,几乎无需时间即可实现适配器模式。

它使用属性反射来访问对象,并支持用户定义的映射。

earc/cast 可以在无需依赖注入的地方使用,甚至在纯函数中也可以。

目录

安装

$ composer require earc/cast

引导

将以下代码片段放置在您的脚本/框架引导部分。

  1. 使用由 composer 命名空间驱动的自动加载。
require_once '/path/to/your/vendor/autoload.php';
  1. 然后引导 earc/cast 以声明 castcast_simplecast_reverse 函数。
use eArc\Cast\Initializer;

Initializer::init();

基本用法

earc/cast 支持四种映射类型:数组到数组数组到对象对象到数组对象到对象

数组到数组

如果省略映射,具有相同键(属性名称)的值将从源分配到目标。

use function eArc\Cast\cast_simple;

$origin = [10, 'a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D'];
$target = [1, 2, 3, 'd' => 'X'];

$result = cast_simple($origin, $target);

// $result = [10, 2, 3, 'd' => 'D']

在提供映射的情况下,映射的键用于源,值用于目标。

提示:如果值为 null,则键用作值。

use function eArc\Cast\cast_simple;

$origin = [10, 'a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D'];
$target = [1, 2, 3, 'd' => 'X'];
$mapping = ['a' => null, 'c' => 'c', 'b' => 'd'];

$result = cast_simple($origin, $target, $mapping);

// $result = [1, 2, 3, 'a' => 'A', 'd' => 'B', 'c' => 'C'];

只有当提供映射时,不存在的键才会创建在目标数组中。

提示:如果提供映射且具有相同键(属性名称)且不在映射中,则不会用于映射值。

数组到对象

如果目标是对象,您可以提供一个实际的对象或类名。在类名的情况下,对象通过反射创建,而不调用构造函数。

use function eArc\Cast\cast_simple;
class MyTargetsParent
{
    public string $a = 'parent_A';
    protected string $b = 'parent_B';
    private string $c = 'parent_C';
    public string $d = 'parent_D';
    protected string $e = 'parent_E';
    private string $f = 'parent_F';
}
class MyTarget extends MyTargetsParent
{
    public function __construct() {
        $this->b = 'constructed_B';
    }
    public string $a = 'A';
    protected string $b = 'B';
    private string $c = 'C';
}

$origin = ['a' => 'array_A', 'c' => 'array_C', 'e' => 'array_E', 'f' => 'array_F'];
$target = new MyTarget();

$result = cast_simple($origin, $target);

// result:
// MyTargetsParent...
//    public string $a = 'array_A'; <-- cast
//    protected string $b = 'constructed_B'; <-- normal inheritance
//    private string $c = 'array_C'; <-- cast 
//    public string $d = 'parent_D';
//    protected string $e = 'array_E'; <-- cast
//    private string $f = 'array_F'; <-- cast
// MyTarget...
//    public string $a = 'array_A'; <-- cast
//    protected string $b = 'constructed_B'; <-- constructor is called
//    private string $c = 'array_C'; <-- cast

$result = cast_simple($origin, MyTarget::class);

// result:
// MyTargetsParent...
//    ...
//    protected string $b = 'B'; <-- normal inheritance
//    ... 
// MyTarget...
//    ...
//    protected string $b = 'B'; <-- constructor was not called
//    ...

对象到数组

如果源对象中存在重写的私有属性,则使用当前类最近的属性。

use function eArc\Cast\cast_simple;
class MyOriginsParent
{
    public string $a = 'parent_A';
    protected string $b = 'parent_B';
    private string $c = 'parent_C';
    public string $d = 'parent_D';
    protected string $e = 'parent_E';
    private string $f = 'parent_F';
}
class MyOrigin extends MyOriginsParent
{
    public string $a = 'A';
    protected string $b = 'B';
    private string $c = 'C';
}

$origin = new MyOrigin();
$target = ['a' => null, 'b' => null, 'c' => null, 'd' => null, 'e' => null, 'f' => null];

$result = cast_simple($origin, $target);

// $result = ['a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'parent_D', 'e' => 'parent_E', 'f' => 'parent_F']

对象到对象

关于对象的所有内容都适用于 数组到对象对象到数组 的情况。

反向映射

有时您需要映射一些属性,应用一个或两个服务,并将对象映射回原始数据表示。

如果目标是对象,您可以使用反向映射来跟踪源和映射。您只需使用 cast 而不是 simple_cast

use function eArc\Cast\cast;
use function eArc\Cast\cast_reverse;

cast($origin, $target, $mapping);

//.. do something with the target;

$origin = cast_reverse($target);

提示:如果您多次以 相同的 目标对象调用 cast,则 cast_reverse 使用最后调用的源和映射。

生成映射

一个常见的用例是使用 earc/cast 生成一个用于前端组件的 json 表示,使用所有公共、受保护和私有属性。不幸的是,earc/cast 使用目标来自动生成映射,因此将对象映射到空数组会使数组为空。generate_mapping 函数是解决方案。

use function eArc\Cast\cast_simple;
use function eArc\Cast\generate_mapping;

return json_encode(cast_simple($object, [], generate_mapping($object)));

高级用法

要覆盖或重写任何逻辑,您必须将实现 CastServiceInterface 的类传递给 Initializer。您可以扩展原始的 CastService。

use eArc\Cast\CastService;
use eArc\Cast\Initializer;

class MyCastService extends CastService
{
    // extend/rewrite logic
}

Initializer::init(new MyCastService());

架构考虑

如果在您的软件设计中遵循依赖倒置原则,应用模块之间不是直接相互依赖,而是依赖于抽象。这比硬耦合的组件更好,但留下了模块必须知道并使用相同抽象的问题。您不能独立开发组件,也不能自由地重用组件。

想象一下商店中滑动产品盒子的滑轨。让滑轨成为整合在商店平台中的内容管理系统的一部分。那么,产品盒滑轨引入了内容管理系统与商店产品销售平台的依赖关系。这就是为什么您不能独立于另一个结构来演进这两个大型结构cms和产品销售平台。如果不能打破大型结构,甚至不应该考虑将小部分分解成独立的应用。最终结果是一个单体架构和数千个(抽象的)依赖关系贯穿整个应用。这是一个噩梦,难以演进和维护。

earc/cast提供了一种实现适配器模式的简单方法。这为您带来了运行时接口多态性的自由。产品盒滑轨可以使用与销售平台不同的产品接口。唯一重要的是底层数据。如果销售平台的产品数据足以满足产品盒滑轨的产品接口,就可以编写适配器并将其映射。现在我们实现了真正的解耦,可以独立于销售平台演进和维护cms。此外,您可以将这两个应用程序分解成更小的部分。唯一需要保持同步的是适配器,在earc/cast的情况下减少为一个简单的单维数组(映射)。

版本

版本 1.1

  • 新函数 generate_mapping
  • 所有功能的文档

版本 1.0

  • PHP >= 8.0

版本 0.0

  • PHP >=5.6