rekalogika/mapper

PHP 和 Symfony 的对象映射器。将一个对象映射到另一个对象。主要用于将实体映射到 DTO 并反向映射。

资助包维护!
priyadi

安装次数: 8,135

依赖关系: 1

建议者: 0

安全: 0

星标: 23

关注者: 2

分支: 1

开放问题: 0

类型:symfony-bundle

v1.8.0 2024-09-22 12:37 UTC

README

rekalogika/mapper 是 PHP 和 Symfony 的对象映射器,也常被称为自动映射器。它将一个对象映射到另一个对象。主要用于将实体映射到 DTO,但也适用于其他映射目的。它简化了对象到对象,甚至对象图到对象图的映射复杂度。

完整文档可在 rekalogika.dev/mapper 查看。

安装

composer require rekalogika/mapper

使用

use App\Entity\Book;
use Rekalogika\Mapper\MapperInterface;

// map a single object:

/** @var MapperInterface $mapper */
/** @var Book $book */

$result = $mapper->map($book, BookDto::class);

// map a single object to an existing object:

$bookDto = new BookDto();
$mapper->map($book, $bookDto);

// map an iterable of objects:

/** @var IterableMapperInterface $iterableMapper */
/** @var iterable<Book> $books */

$bookDtos = $iterableMapper->mapIterable($books, BookDto::class);

为什么使用映射器?

我们为什么要使用映射器来节省几个按键,而不是简单地使用像这样简单的东西?

class BookDto
{
    public static function create(Book $book): self
    {
        $dto = new self();
        // ...

        return $dto;
    }
}

每个人在某个时刻都会有这样的想法。然而,随着项目的增长,目标类(DTO)可能会开始相互引用,形成一个丰富的对象图。你的代码将开始出现许多特殊情况,不再是你想象的那样简单。它变得难以维护,最终迫使你坐下来尝试解决问题。当你(如果)成功设计出解决方案时,你最终会得到一个类似于映射框架的东西。

映射可以是简单的,但也可以变得非常复杂。映射器的创建是为了处理这种复杂性,而不仅仅是为了节省几个按键。

特性

通用

  • 自动列出源和目标属性的列表,检测其类型,并相应地映射它们。
  • 从 PHP 类型声明和 PHPDoc 注释中读取类型,包括嵌套对象的类型。
  • 不会尝试绕过你的类约束。只从公共属性、获取器和设置器读取,只写入公共属性、获取器和设置器。不会在没有构造函数的情况下实例化对象。
  • 构造函数初始化。
  • 处理嵌套对象。
  • 处理递归和循环引用。
  • 支持继承。使用继承映射属性将映射到抽象类和接口。
  • 映射到和从 stdClass,扩展 stdClass 的对象,以及其他具有动态属性的对象(#[AllowDynamicProperties])。
  • 将对象映射到数组,反之亦然。
  • 支持第三方对象:Doctrine 集合、Symfony Uid、Ramsey UUID。

自定义映射

  • 使用自定义属性映射器覆盖特定属性的映射。
  • 使用自定义对象映射器覆盖两个特定类之间的映射。
  • 通过创建新的转换器或装饰现有的转换器来扩展映射器。
  • 除了使用类名外,还使用转换器中的属性匹配类。
  • 预设映射。提供一张预定的映射表,映射器可以使用。

对象懒加载

  • 如果可能,目标对象将懒加载。映射将在目标对象被访问时进行,如果从未被访问,则永远不会进行映射。
  • 在源端尝试检测标识符属性。这些属性将被贪婪地映射到目标端,因为它们不应该触发源端的激活。以API Platform为例,它可以在不引起Doctrine激活整个对象图的情况下生成IRI。

数组和类似数组的对象

  • 处理array或类似数组的对象的映射。
  • 处理目标端的添加器和移除方法。
  • 处理类似数组对象中的非字符串和非整数字符键,包括SplObjectStorage
  • 如果它们在源端不存在,可以选择从目标端删除现有项目。

类似数组的延迟加载

  • 如果目标被类型提示为ArrayAccessTraversableCollectionInterface,则进行延迟加载。目标将在访问之前不会迭代源对象,或者在从未访问过时永远不会迭代。
  • 流映射。在迭代时将源成员映射到目标端,这可能会消耗更少的内存。
  • 在延迟加载的情况下,如果源是Countable,则目标也将是Countable。对于额外的延迟加载Doctrine集合,消费者可以在不引起源端完全激活的情况下计算目标。

开发体验(DX)

  • 有用的异常消息。
  • 用于调试的控制台命令。
  • 数据收集器和分析器集成。
  • 从头开始使用PHP 8、严格类型以及PHPStan和Psalm的最大级别编码。

待办事项列表

  • 读取和写入私有属性的选项。
  • 将迁移引擎迁移到symfony/type-info
  • 自动检测静态工厂方法。
  • 使用我们自己的接口用于代理对象。
  • 改进非框架使用。
  • 从用户提供的类列表中在构建时预热代理。

文档

rekalogika.dev/mapper

许可证

MIT