futuretek/data-mapper
Composer 安装命令:
composer require futuretek/data-mapper
包简介
A lightweight, reflection-based PHP 8.4+ data mapping library for converting associative arrays into typed PHP objects (POPOs), and back. Ideal for OpenAPI-generated DTOs, form handling, and request/response serialization in modern API architectures.
关键字:
README 文档
README
A lightweight PHP 8.4+ utility for mapping associative arrays to plain PHP objects (POPOs) and vice versa, using reflection and PHP attributes.
Features
- ⚙️ Supports native PHP 8.4+ typed properties (scalars, nullable,
mixed,object,iterable) - 📌 Declarative mapping via custom attributes
- 📅 Handles date and datetime format conversions via
#[Format] - 🗂️ Supports typed arrays of objects via
#[ArrayType] - 📅 Supports arrays of date / date-time strings via
#[ArrayType(\DateTimeInterface::class, format: '...')] - 🗺️ Supports associative maps via
#[MapType] - 📁 Supports file mapping via
SplFileObjectand PSR-7UploadedFileInterface - 🧩 Backed enum handling with
tryFrom - 🔄 Nested object mapping (recursive)
- 🔒 Readonly property support via reflection
- 🔐 PHP 8.4 asymmetric visibility support (e.g.,
public private(set)) - 🔍 Optional strict validation for required properties
- ✅ Converts objects back to associative arrays (
toArray) - 🚫 Skips non-public and static properties
- 💪 Gracefully handles uninitialized properties in
toArray
Installation
composer require futuretek/data-mapper
Usage
Define DTO with Attributes
use futuretek\datamapper\attributes\ArrayType; use futuretek\datamapper\attributes\MapType; use futuretek\datamapper\attributes\Format; class BlogPost { public string $title; public ?string $subtitle = null; #[Format('date-time')] public \DateTimeImmutable $publishedAt; #[ArrayType(Comment::class)] public array $comments; #[ArrayType(\DateTimeInterface::class, format: 'date')] public array $holidays; #[MapType(valueType: Tag::class)] public array $tags; public StatusEnum $status; public Author $author; public readonly string $slug; }
Map From Array
use futuretek\datamapper\DataMapper; $dto = DataMapper::toObject($dataArray, BlogPost::class);
Convert Back To Array
$array = DataMapper::toArray($dto);
Configuration
// Throw InvalidArgumentException when a non-nullable property is missing from input DataMapper::$validateRequiredProperties = true; // Set a factory for converting file resources to PSR-7 UploadedFileInterface DataMapper::$fileFactory = new MyFileFactory();
Custom Attributes
#[Format]
Parses date strings into DateTimeImmutable instances.
#[Format('date')] // Parses "2025-06-17" using Y-m-d format public \DateTimeInterface $birthDate; #[Format('date-time')] // Parses "2025-06-17T15:00:00+00:00" using ISO 8601 / ATOM format public \DateTimeInterface $createdAt;
When converting back via toArray, a DateTimeInterface property without #[Format] defaults to date-time format.
#[ArrayType]
Declares the item type of an array property — supports class names, scalar type names, and DateTimeInterface with a format.
#[ArrayType(Comment::class)] // Array of objects — each item is recursively mapped public array $comments; #[ArrayType('int')] // Array of scalars — items are passed through as-is public array $scores; #[ArrayType(\DateTimeInterface::class, format: 'date')] public array $holidays; // Array of "Y-m-d" strings ↔ DateTimeImmutable[] #[ArrayType(\DateTimeInterface::class, format: 'date-time')] public array $events; // Array of ISO 8601 strings ↔ DateTimeImmutable[]
When format is provided:
toObject— each string item is parsed into aDateTimeImmutable; an unparseable item becomesnull.toArray— eachDateTimeInterfaceitem is formatted back to a string (Y-m-dfor'date', ATOM for'date-time').
#[MapType]
Declares a property as an associative map (string keys to typed values).
#[MapType(valueType: Tag::class)] // Map of objects — values are recursively mapped public array $tags; #[MapType(valueType: 'string')] // Map of scalars — values are passed through as-is public array $translations;
Supported Property Types
| Type | toObject Behavior |
toArray Behavior |
|---|---|---|
string, int, float, bool |
Assigned directly | Returned as-is |
Nullable (?type) |
null values accepted; missing keys use default |
null returned |
DateTimeInterface + #[Format] |
Parsed from string via new DateTimeImmutable() |
Formatted to string |
array + #[ArrayType(ClassName)] |
Items mapped recursively | Items converted recursively |
array + #[ArrayType(\DateTimeInterface::class, format: 'date|date-time')] |
Each string item parsed into DateTimeImmutable |
Each item formatted back to string |
array + #[MapType] |
Values mapped recursively if class type | Values converted recursively |
Backed enum |
Resolved via tryFrom() |
Serialized to backing value |
| Nested class | Recursively mapped from sub-array | Recursively converted to sub-array |
object |
Cast from array via (object) |
JSON encode/decode to array |
mixed |
Assigned as-is | Returned as-is |
UploadedFileInterface |
Assigned directly or via $fileFactory |
Returned as-is |
SplFileObject |
Assigned directly | Returned as-is |
readonly |
Set via reflection | Returned normally |
public private(set) |
Set via reflection | Returned normally |
Untyped (public $x) |
Assigned as-is | Returned as-is |
Property Handling Rules
- Non-public properties (private, protected) are skipped.
- Static properties are always skipped.
- Unknown keys in the input array are silently ignored.
- Missing non-nullable properties with
$validateRequiredProperties = truethrowInvalidArgumentException. - Missing non-nullable properties with
$validateRequiredProperties = falseremain uninitialized. - Uninitialized properties are skipped during
toArrayconversion. - Invalid enum values throw
UnexpectedValueException. - Malformed date strings result in
null(viaDateTimeImmutable::createFromFormatreturningfalse).
File Handling
Supports SplFileObject and PSR-7 UploadedFileInterface properties.
For UploadedFileInterface properties, if the input value is already an UploadedFileInterface instance, it is assigned directly. Otherwise, the configured FileFactoryInterface is used to convert the value. If no factory is configured, a RuntimeException is thrown.
Implementing FileFactoryInterface
use futuretek\datamapper\FileFactoryInterface; use Psr\Http\Message\UploadedFileInterface; class MyFileFactory implements FileFactoryInterface { public function createFromResource(mixed $resource): UploadedFileInterface { if (is_string($resource)) { // Handle file path $stream = fopen($resource, 'r'); return new MyUploadedFile($stream, filesize($resource), basename($resource)); } throw new \InvalidArgumentException('Unsupported resource type: ' . gettype($resource)); } }
Limitations
- Union types (e.g.,
int|string) are not supported. - Intersection types are not supported.
- The constructor is bypassed via
newInstanceWithoutConstructor()— constructor logic will not run. DateTimeImmutableis always used for date parsing, regardless of whether the property type isDateTimeorDateTimeInterface.
License
Apache License 2.0
futuretek/data-mapper 适用场景与选型建议
futuretek/data-mapper 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 802 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 06 月 25 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「data mapper」 「cute」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 futuretek/data-mapper 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 futuretek/data-mapper 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 futuretek/data-mapper 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Shoot aims to make providing data to your templates more manageable
data-mapper php library
Convention-based Alternative ORM
Adds the EDTF data type to Wikibase
A simple library that allows transform any kind of data to native php data or whatever
Data provider for yii2
统计信息
- 总下载量: 802
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 9
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: Apache-2.0
- 更新时间: 2025-06-25