earc / cast
eArc - 显式架构框架 - cast 组件
Requires
- php: >=8.0
Requires (Dev)
- phpunit/phpunit: 8.5.*
- symfony/var-dumper: ^5.2
This package is auto-updated.
Last update: 2024-09-29 05:29:19 UTC
README
earc/cast 是一个轻量级无依赖的扁平数据映射器,可以将由对象/数组表示的数据映射到其他对象/数组上。因此,几乎无需时间即可实现适配器模式。
它使用属性反射来访问对象,并支持用户定义的映射。
earc/cast 可以在无需依赖注入的地方使用,甚至在纯函数中也可以。
目录
安装
$ composer require earc/cast
引导
将以下代码片段放置在您的脚本/框架引导部分。
- 使用由 composer 命名空间驱动的自动加载。
require_once '/path/to/your/vendor/autoload.php';
- 然后引导 earc/cast 以声明
cast
、cast_simple
和cast_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