makinacorpus / generated-hydrator-bundle
为 Symfony 提供ocramius/generated-hydrator的集成
Requires
- php: >=8.0
- ocramius/generated-hydrator: ^4.3
Requires (Dev)
- phpdocumentor/reflection-docblock: ^5.3
- phpunit/phpunit: ^8.5
- ramsey/uuid: ^4.0
- symfony/config: ^5.0|^6.0
- symfony/dependency-injection: ^5.0|^6.0
- symfony/filesystem: ^5.0|^6.0
- symfony/http-kernel: ^5.0|^6.0
- symfony/property-info: ^5.0|^6.0
- symfony/yaml: ^5.0|^6.0
This package is not auto-updated.
Last update: 2024-09-24 15:53:13 UTC
README
集成 ocramius/generated-hydrator 库与 Symfony。
它还带来了一些新功能
-
嵌套 hydrator,从 PHP 属性类型将 hydration 传递到对象图中。
-
值 hydrator,对于每个 PHP 类型,您可以插入自己的全局 hydrator 实现来处理自定义类型。
-
下一个计划的功能将是使用属性进行对象配置。
安装
首先安装依赖项
composer require makinacorpus/generated-hydrator-bundle
然后将它添加到您的 config/bundles.php
文件中
<?php return [ // ... \GeneratedHydrator\Bridge\Symfony\GeneratedHydratorBundle::class => ['all' => true], ];
配置
更改生成的 PHP 文件位置
默认配置将尝试将生成的 hydrator 代码写入到 %kernel.project_dir%/hydrator
文件夹。为此,您可能需要在您的 composer.json
文件中添加以下内容
{ "autoload": { "classmap": [ "hydrator" ] } }
您可以通过添加以下 config/packages/generated-hydrator.yaml
文件来更改目标
generated_hydrator: target_directory: "%kernel.project_dir%/hydrator"
禁止从 hydration 中加载类
在某些时候,当 hydrator 尝试例如 hydration PHP 核心类时,您可能会遇到错误。为了避免这种情况,您可以使用以下配置完全禁用任何 PHP 类的 hydration 尝试
generated_hydrator: class_blacklist: - App\SomeClass - DateTime - DateTimeImmutable - DateTimeInterface - Ramsey\Uuid\Uuid - Ramsey\Uuid\UuidInterface # ...
这将防止嵌套对象 hydrator 对这些类的 hydration 尝试。
为生产预先生成类 hydrator
您可以设置一个需要预先生成 hydrator 的类的列表
generated_hydrator: class_list: - App\Entity\Foo - App\Entity\Bar # ...
这将允许 generated-hydrator:generate
命令预先生成所有 hydrator。
自动装配
您可以使用 GeneratedHydrator\Bridge\Symfony\HydratorAware
接口并在服务上设置它,这将使此捆绑包为您自动配置服务注入。
如果您不想自己实现 setObjectHydrator()
方法,您也可以使用 GeneratedHydrator\Bridge\Symfony\HydratorAwareTrait
。
使用方法
基本使用
注入 generated_hydrator
服务,或使用 GeneratedHydrator\Bridge\Symfony\Hydrator
进行类型提示来自动装配。
为了 hydration 一个对象
use App\Domain\Model\SomeEntity; use GeneratedHydrator\Bridge\Symfony\Hydrator; function some_function(Hydrator $hydrator) { $object = $hydrator->createAndHydrate( SomeEntity::class, [ // Scalar values 'foo' => 1, // ... // It also handles nested objects 'bar' => [ 'baz' => 2, // ... ], ] ); }
或提取其值
use App\Domain\Model\SomeEntity; use GeneratedHydrator\Bridge\Symfony\Hydrator; function some_function(Hydrator $hydrator) { $object = new SomeEntity(); $valueArray = $hydrator->extract($object); }
值 hydrator
让我们假设您有以下类
namespace App\Entity; interface Identifier { public function __construct(mixed $value); public function __toString(): string; } class FooId { public function __construct( private mixed $value, ) {} public function __toString(): string { return (string) $this->id; } }
并将其用作以下实体类的标识符类
namespace App\Entity; class Foo { public function __construct( private FooId $id, ) {} // ... }
如果您需要使用以下数据库中的数据 hydration 一些 Foo
实例
$foo = $hydrator->createAndHydrate( \App\Entity\Foo::class, [ 'id' => '12345', ], );
这将失败,因为 $id
参数不能接受一个 string
值。
如果您在网站上到处都使用相同的模式,您可能希望使用全局值 hydrator,如下所示
namespace App\ValueHydrator; use App\Entity\Identifier; use GeneratedHydrator\Bridge\Symfony\Error\CannotHydrateValueError; use GeneratedHydrator\Bridge\Symfony\ValueHydrator\ValueHydrator; class IdentifierValueHydrator implements ValueHydrator { /** * {@inheritdoc} */ public function supports(string $phpType): bool { return \is_subclass_of($phpType, Identifier::class); } /** * {@inheritdoc} */ public function hydrate(string $phpType, mixed $value): mixed { if (\is_subclass_of($phpType, Identifier::class)) { return new $phpType($value); } throw new CannotHydrateValueError(); } }
您可以通过显式设置 generated_hydrator.value_hydrator
服务标签,或将它添加到容器中,通过将 autowiring
和 autoconfiguration
设置为 true
在此服务上来实现注册
services: App\ValueHydrator\IdentifierValueHydrator: autowire: true autoconfigure: true
一旦设置,每个需要 hydration 实现您的 App\Entity\Identifier
接口的属性值都将自动正确实例化。
一些注意事项
为了使嵌套 hydrator 能够工作,它需要能够使用反射对您的类进行元编程,以找到属性类型。
如果由于某种原因元编程失败,您可以显式安装 symfony/property-access
组件,它可能找到一些此 API 使用反射无法找到的类型。
路线图
达到 alpha 版本(强制)
- 实现类黑名单,一些类如
\DateTime
和\Ramsey\Uuid\
应被视为终端类型,并在业务层中进行归一化处理。 - 当类生成时自动加载类,
- 自动注册生成 hydrator 类的回退自动加载器,没有这个,缓存目录中生成的类将不可自动加载。
工业化(1.0)
- 允许 API 用户无需显式使用嵌套实现即可使用 hydrator,可能使用特定的接口和特定的服务标识符,
- 嵌套 hydrator 是一种权宜之计,它不应是默认设置,
- 为用户编写高级配置,
- 编写更多测试,大量测试。
远在天边
- 处理嵌套提取/填充中的集合,
- 添加一个选项,即使类已加载,也禁用属性信息的使用,
- 为了替换我们的自定义解析器,移除 PHP docblock 解析器,为此,我们需要能够解析相对类命名空间。