ok / dto-annotation-mapper
数据映射器
Requires
- php: >=7.4
- ext-json: *
- doctrine/orm: ^2
Requires (Dev)
- phpunit/phpunit: ^4.8 || ^5.0
README
这个库旨在根据注解自动填充实体对象。
用途
如果您有多种情况需要从数组数据填充实体,则此库可能非常有用。
例如,您从客户端检索数据并创建新实体,另一种方式是从导入文件中获取此实体。
您无需创建单独的服务来从数组数据集中填充实体,只需指定要填充的实体字段,并传递您需要的那些属性即可。
要求
- PHP 7.4+
- Doctrine ORM 2+
安装
您可以通过 composer 安装此包
composer require ok/dto-annotation-mapper
对于 Symfony 项目:在 services.yml
中将 AnnotationMapper 注册为服务
OK\Dto\MapperInterface: class: OK\Dto\AnnotationMapper autowire: true
对于其他项目,只需初始化新的映射器对象
use Doctrine\Common\Annotations\AnnotationReader; $mapper = new AnnotationMapper(new AnnotationReader(), $entityManager);
用法
首先,您需要使用 DTO 注解标记 doctrine 实体中的设置器
/** * @ORM\Entity(repositoryClass="App\Repository\ProductRepository") */ class Product { /** * @var string * * @ORM\Column(type="string", nullable=true) */ protected $article; /** * @var Material * * @ORM\ManyToOne(targetEntity="App\Entity\Product\Options\Material") */ protected $material; /** * @DTO(name="article", type="string") */ public function setArticle(?string $article) { $this->article = $article; } /** * @DTO(name="material", type="App\Entity\Product\Options\Material", relation="ManyToOne") */ public function setMaterial(?Material $material) { $this->material = $material; }
然后,只需将对象和输入数据传递到控制器中的 fillObject
方法,如下所示(以 Symfony 项目为例,但您可以使用任何框架或无需框架)
/** * @Route("/products/{id}", name="api_product_patch", methods={"PATCH"}) */ public function updateProductAction(Request $request, Product $product, MapperInterface $mapper): JsonResponse { $data = $this->getRequestData($request); $updatedProduct = $mapper->fillObject($product, $data); /* Do validation and other actions if need */ $this->getDoctrine()->getManager()->flush(); return $this->json($updatedProduct); }
这就完成了!您的实体将更新为新数据。
支持的简单类型:string
、float
、bool
、boolean
、int
、integer
、datetime
、array
。尝试使用其他类型而无需 relation
将会抛出 OK\Dto\Exception\MapperInvalidTypeException
。
您可以使用任何实体类作为类型,您只需指定它的 relation
:ManyToOne
、OneToMany
、ManyToMany
测试
composer install vendor/bin/phpunit tests
信息
基本用法
如果 property
设置或 type
未在 DTO
注解中设置,则所有有用的信息都将从 Doctrine
注解中检索。
@DTO(name="material") @DTO(name="material_name", property="material")
仅使用简单类型
即使不使用 Doctrine\orm
,您也可以使用此映射器。
只需创建映射器,不使用第二个参数,并根据需要使用您自己的 Reader
实现。
new \OK\Dto\AnnotationMapper(new \Doctrine\Common\Annotations\AnnotationReader());
然后您可以使用简单类型。
大小写敏感
您可以在 name
字段中使用 snake_case
和 camelCase
,映射器将在数据集中检查这两种变体的严格键。例如:如果您有注解
@DTO(name="customerNumber", type="string")
和数据集
$data = ['customer_number' => 123];
这是可以的。首先映射器检查严格的名称 customerNumber
,然后(如果名称不存在)将其转换为 customer_number
并再次检查。它也可以以相反的方式工作(从 snake_case
到 camelCase
)。
多个命名
如果您需要为单个 Dto
注解设置多个名称,请通过 |
分隔符列出它们,然后您可以在不同情况下使用不同的名称在数据中。
@DTO(name="customerNumber|userNumber|managerNumber", type="string")
如果在数据集中存在这个集合中的多个名称,则映射器将返回第一个找到的。
使用 ManyToMany 关系
要使用 ManyToMany
关系,您需要为您的事件仓库实现 OK\Dto\Repository\SearchCollectionInterface
或您可以从 OK\Dto\Repository\EntityRepository
继承。
使用 OneToMany 关系
这里有两种使用这种关系的方法
第一种是当相关实体存在时,您需要将 id 数组传递到数据集中
$data = ['customers' => [1,2,3]];
当您需要创建新的实体时,您需要传递数据以创建
$data = ['customers' => [['firstName' => 'John', 'lastName' => 'Smith']]];
您可以将这两种方式结合在一个数据集中
$data = ['customers' => [1, 2, ['firstName' => 'John', 'lastName' => 'Smith']];
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。