sunrise/hydrator
Composer 安装命令:
composer require sunrise/hydrator
包简介
Strictly typed object hydration and value casting.
README 文档
README
Languages: 🇬🇧 English | 🇷🇺 Русский
The package hydrates object properties from arrays and JSON with casting to declared PHP types. Individual values can also be cast without hydrating an object.
Installation
composer require sunrise/hydrator
The package supports PHP 7.4 and newer. Examples in this README target PHP 8+.
Object Hydration
use Sunrise\Hydrator\Annotation\Filter; use Sunrise\Hydrator\Annotation\ItemType; use Sunrise\Hydrator\Hydrator; final class CreateUserRequest { #[Filter('trim')] public string $email; public bool $isActive; #[ItemType('string', limit: 10)] public array $roles = []; } $request = (new Hydrator())->hydrate(CreateUserRequest::class, [ 'email' => ' user@example.com ', 'isActive' => 'true', 'roles' => ['user', 'editor'], ]);
The hydrator:
- creates an object without calling its constructor or fills an existing object;
- skips properties marked with
#[Ignore]; - ignores input keys that do not match any property;
- hydrates nested objects recursively;
- collects property and element hydration errors into one
InvalidDataException.
An input value is required when the corresponding property is not initialized and no default value is defined for it. A default value can be defined in the property declaration, in the constructor parameter with the same name, or through #[DefaultValue].
Default values are used only when the input key is missing. A passed null is treated as an input value and is validated against the property type.
Hydration from JSON
$request = (new Hydrator())->hydrateWithJson( CreateUserRequest::class, '{"email":"user@example.com","isActive":true}' );
The root JSON value must be an object or an array.
Value Casting
use Sunrise\Hydrator\Dictionary\BuiltinType; use Sunrise\Hydrator\Hydrator; use Sunrise\Hydrator\Type; $value = (new Hydrator())->castValue( '42', Type::fromName(BuiltinType::INT) );
Supported Types
| PHP type | Accepted input values |
|---|---|
mixed |
Any value |
bool |
bool or the strings 1, 0, true, false, yes, no, on, off |
int |
int or a string representation of an integer |
float |
float, int, or a string representation of a number |
string |
string or int |
array |
array or stdClass |
DateTimeImmutable and subclasses |
A string in the configured format; an integer or string for format U |
DateInterval |
A string accepted by the DateInterval constructor |
DateTimeZone |
A timezone identifier |
| A concrete backed enum | A value of the corresponding backing type; for int, a string representation of an integer is also accepted |
| An instantiable user-defined class | array or stdClass |
A class implementing ArrayAccess |
array or stdClass |
Also supported:
| Type | Package |
|---|---|
A subclass of MyCLabs\Enum\Enum |
myclabs/php-enum |
Ramsey\Uuid\UuidInterface |
ramsey/uuid |
Subclasses of Symfony\Component\Uid\AbstractUid |
symfony/uid |
null is accepted only for a type that allows null.
For booleans, numbers, dates, intervals, timezones, enums, UUIDs, and UIDs, an empty string after trimming is treated as a missing value: null is returned for a nullable type; otherwise an InvalidValueException is thrown.
Union and intersection types are not supported.
Arrays and Collections
#[ItemType] defines the type of array or collection elements and optionally limits their count:
use Sunrise\Hydrator\Annotation\ItemType; final class OrderRequest { #[ItemType(OrderItemRequest::class, limit: 100)] public array $items; }
Each element will be cast to the declared type. The allowsNull parameter allows null values in elements:
#[ItemType('int', allowsNull: true, limit: 100)] public array $ids;
For an instantiable class implementing ArrayAccess, the element type can also be inferred from the type of the last constructor parameter declared with ...:
final class UserCollection extends ArrayObject { public function __construct(User ...$users) { parent::__construct($users); } }
The constructor is not called during hydration: the hydrator only reads the type of its last variadic parameter and creates the object without the constructor. An explicit #[ItemType] takes precedence over the constructor parameter type.
If the collection throws OverflowException while adding an element, the hydrator treats it as an element limit overflow and returns an array overflow error to the user.
Element Types from PHPDoc
The hydrator can read the element type of an array property from @var:
final class OrderRequest { /** @var list<OrderItemRequest> */ public array $items; } $hydrator = new Hydrator(isDocBlockReaderEnabled: true);
PHPDoc reading is disabled by default. #[ItemType] takes precedence over @var.
@var is not used for classes implementing ArrayAccess. Use #[ItemType] or the type of the variadic constructor parameter instead.
Attributes
| Attribute | Purpose |
|---|---|
#[Alias('external-name')] |
Defines the input key for a property |
#[Context([...])] |
Defines or overrides context values for a property or parameter |
#[DefaultValue(...)] |
Defines a value used when the input key is missing |
#[Filter(...)] |
Transforms the input value before type casting |
#[Format('...')] |
Defines the date and time format |
#[Ignore] |
Excludes a property from hydration |
#[ItemType(...)] |
Defines the element type and maximum element count |
#[Filter] can be used more than once. Filters are applied in sequence:
use Sunrise\Hydrator\Annotation\Filter; #[Filter('trim')] #[Filter('strtolower')] public string $email;
#[Filter] is available only on PHP 8.0 and newer.
Date, Time, and Context
By default, DateTimeImmutable uses the DateTimeInterface::RFC3339_EXTENDED format.
Format and timezone can be configured for a hydrator instance:
use DateTimeInterface; use Sunrise\Hydrator\Dictionary\ContextKey; use Sunrise\Hydrator\Hydrator; $hydrator = new Hydrator(context: [ ContextKey::TIMESTAMP_FORMAT => DateTimeInterface::RFC3339_EXTENDED, ContextKey::TIMEZONE => 'Europe/Belgrade', ]);
Operation-specific context is passed to hydrate() or castValue(). Use #[Context] and #[Format] for a property or parameter:
use Sunrise\Hydrator\Annotation\Context; use Sunrise\Hydrator\Annotation\Format; use Sunrise\Hydrator\Dictionary\ContextKey; #[Format('Y-m-d')] #[Context([ContextKey::TIMEZONE => 'UTC'])] public DateTimeImmutable $date;
Precedence order:
- attribute context;
- operation context;
- hydrator context.
Errors
hydrate() collects individual value errors into InvalidDataException:
use Sunrise\Hydrator\Exception\InvalidDataException; try { $request = $hydrator->hydrate(CreateUserRequest::class, $data); } catch (InvalidDataException $e) { foreach ($e->getExceptions() as $error) { echo $error->getPropertyPath() . ': ' . $error->getMessage() . PHP_EOL; } }
InvalidValueException provides:
getPropertyPath()— dot-separated value path;getErrorCode()— error code;getMessage()— resolved message;getMessageTemplate()— message template;getMessagePlaceholders()— template parameters;getInvalidValue()— original value;getTranslationDomain()— translation domain.
Method exceptions:
hydrate()throwsInvalidDataExceptionfor input value errors andInvalidObjectExceptionwhen the object cannot be created or a property has an unsupported type;hydrateWithJson()additionally usesInvalidDataExceptionfor JSON decoding errors and an invalid root value;castValue()throwsInvalidValueExceptionfor a single invalid value,InvalidDataExceptionfor nested object or array errors, andInvalidObjectExceptionfor an unsupported target type.
If symfony/validator is installed, InvalidValueException::getViolation() and InvalidDataException::getViolations() return violations in the Symfony Validator format.
Custom Type Converters
A converter implements TypeConverterInterface. If the type is not supported, the method returns without a result. If it is supported, it yields the result or throws an exception.
use Generator; use Sunrise\Hydrator\Exception\InvalidValueException; use Sunrise\Hydrator\Type; use Sunrise\Hydrator\TypeConverterInterface; final class MoneyTypeConverter implements TypeConverterInterface { public function castValue( $value, Type $type, array $path, array $context ): Generator { if ($type->getName() !== Money::class) { return; } if (!is_string($value)) { throw InvalidValueException::mustBeString($path, $value); } yield Money::fromString($value); } public function getWeight(): int { return 100; } }
A converter can be passed to the constructor or added later:
$hydrator = new Hydrator(typeConverters: [ new MoneyTypeConverter(), ]); $hydrator->addTypeConverter(new MoneyTypeConverter());
Converters are called in descending weight order. Implement HydratorAwareInterface or AnnotationReaderAwareInterface if a converter needs access to the hydrator or the annotation reader.
Compatibility
On PHP 8.0 and newer, attributes are read automatically. On PHP 7.4, Doctrine Annotations can be used for Alias, Context, DefaultValue, Format, Ignore, and ItemType:
composer require doctrine/annotations
use Sunrise\Hydrator\AnnotationReader\DoctrineAnnotationReader; $hydrator->setAnnotationReader(DoctrineAnnotationReader::default());
On PHP 7, only DateTimeImmutable itself is supported, not its subclasses. Built-in enums are supported starting with PHP 8.1.
Deprecated names #[Subtype] and #[Relationship] are kept for backward compatibility. Use #[ItemType] in new code.
sunrise/hydrator 适用场景与选型建议
sunrise/hydrator 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 33.76k 次下载、GitHub Stars 达 21, 最近一次更新时间为 2021 年 03 月 26 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「hydrator」 「hydration」 「type casting」 「type caster」 「type converter」 「type conversion」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 sunrise/hydrator 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 sunrise/hydrator 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 sunrise/hydrator 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A bundle providing fields for image upload with jquery upload and image cropping with jcrop for symfony2
A simple Symfony bundle that adds boolean form field type.
Library for merging source data to destination data only if destination data remains valid after that
Hydrator to map or extract an extract object
Integrates data-mapper in Symfony projects.
A PHP Abstract Enum Class
统计信息
- 总下载量: 33.76k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 21
- 点击次数: 14
- 依赖项目数: 5
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2021-03-26