jooservices/dto
最新稳定版本:1.0.0
Composer 安装命令:
composer require jooservices/dto
包简介
Data Transfer Object (DTO)
README 文档
README
A powerful, lightweight Data Transfer Object (DTO) package for PHP 8.5+.
Developer Information
Developer: Viet VU
Email: jooservices@gmail.com
URL: jooservices.com
Why JOOservices DTO?
- ✨ Zero Dependencies - Pure PHP 8.5+, no bloat
- 🚀 High Performance - Reflection-based with opcache optimization
- 🎯 Type Safe - Full type hinting and validation
- 🔧 Extensible - Custom casts, transformers, normalizers
- 📦 Framework Agnostic - Works everywhere
- 🧩 Modular - Trait-based composition architecture
Comparison
| Feature | JOOservices DTO | Spatie DTO | Spatie Laravel Data |
|---|---|---|---|
| PHP 8.5+ Required | ✅ | ❌ | ❌ |
| Zero Dependencies | ✅ | ❌ | ❌ |
| Framework Agnostic | ✅ | ✅ | ❌ (Laravel only) |
| Built-in Validation | ✅ | ❌ | ✅ |
| Type Casting | ✅ | ✅ | ✅ |
| Property Mapping | ✅ | ❌ | ✅ |
| Output Transformers | ✅ | ❌ | ✅ |
| JSON Serialization | ✅ | ✅ | ✅ |
| Nested DTOs | ✅ | ✅ | ✅ |
| Collections Support | ✅ | ❌ | ✅ |
| Accessors/Mutators | ✅ | ❌ | ✅ |
| Lightweight | ✅ | ✅ | ❌ |
💡 Tip: Choose JOOservices DTO if you need a lightweight, zero-dependency solution with modern PHP 8.5+ features and comprehensive validation.
Table of Contents
Features
- ✅ Immutable by Default:
Dtoclass is immutable (read-only) ensuring data integrity - ✅ Mutable Option:
Dataclass provides mutable behavior for flexible use cases - ✅ Clean Architecture: Both
DtoandDataextendAbstractDtoas siblings (not parent-child) - ✅ Immutable Updates: Use
with()method to create new instances with updated properties - ✅ Type Safety: Strongly typed properties with PHP 8.5+ type hints
- ✅ Array Transformation: Easy conversion to/from arrays
- ✅ JSON Serialization: Built-in JSON encoding support
- ✅ Nested DTOs: Support for nested DTO objects
- ✅ Array of DTOs: Handle collections of DTOs
- ✅ Reflection-based: Automatic property mapping using reflection
- ✅ Property Mapping: Map input keys to different property names with
#[MapFrom] - ✅ Validation Rules: Built-in validation attributes (
#[Email],#[Min],#[Max],#[Regex]) - ✅ Output Transformers: Transform property values during serialization with
#[WithTransformer] - ✅ Pipeline Processing: Process DTOs through multiple transformation steps with error handling and rollback
- ✅ Zero Dependencies: Pure PHP, no external dependencies required
- ✅ Framework Agnostic: Works with any PHP 8.5+ application
Quick Start
Installation
composer require jooservices/dto
📖 For detailed installation instructions, see Installation Guide
Basic Usage
📖 For comprehensive usage examples, see Getting Started Guide
Dto vs Data: Immutable vs Mutable
The package provides two base classes that are siblings (both extend AbstractDto):
-
Dto- Immutable (read-only after creation). Properties cannot be modified after creation. Use thewith()method to create new instances with updated properties. Perfect for data transfer where immutability ensures data integrity. -
Data- Mutable. Properties can be modified after creation usingsetProperty()or direct assignment. Use when you need to build or modify DTOs incrementally.
Architecture Note: Both Dto and Data extend AbstractDto as siblings, not in a parent-child relationship. This design complies with the Liskov Substitution Principle and eliminates code duplication through SharedBaseTrait.
Quick Comparison Table
| Feature | Dto (Immutable) |
Data (Mutable) |
|---|---|---|
| Mutability | ❌ Read-only after creation | ✅ Can be modified |
| Property Assignment | ❌ $dto->prop = value throws exception |
✅ $data->prop = value works |
| Update Method | ✅ with() creates new instance |
✅ Direct assignment or setProperty() |
| Accessors | ✅ Supported (computed properties) | ✅ Supported (computed properties) |
| Mutators | ❌ Not supported | ✅ Supported (transform on set) |
| Use Case | API responses, DB results, configs | Form data, user input, incremental building |
| Immutability Guarantee | ✅ Strong (cannot modify after creation) | ❌ Mutable (can modify anytime) |
| Thread Safety | ✅ Safe (immutable) | ⚠️ Not thread-safe (mutable) |
When to use each:
- Use
Dtofor: API responses, database results, configuration objects, or any scenario where data should remain unchanged after creation. - Use
Datafor: Form data, user input processing, or any scenario where you need to modify properties after creation.
📖 For detailed information on extending classes, see Extending Classes Guide
Creating a DTO
Extend the base Dto class and define your properties as public:
💡 Tip: Always use type hints for properties to enable automatic type casting and validation.
use JOOservices\Dto\Dto; class UserDto extends Dto { public function __construct( public string $name, public string $email, public ?int $age = null, ) { } }
Creating DTO from Array
$user = UserDto::fromArray([ 'name' => 'John Doe', 'email' => 'john@example.com', 'age' => 30, ]);
Converting DTO to Array/JSON
$user = new UserDto('John Doe', 'john@example.com', 30); // To array $array = $user->toArray(); // ['name' => 'John Doe', 'email' => 'john@example.com', 'age' => 30] // To JSON $json = $user->toJson(); // {"name":"John Doe","email":"john@example.com","age":30}
Nested DTOs
use JOOservices\Dto\Dto; class CategoryDto extends Dto { public function __construct( public int $id, public string $name, public string $slug, ) { } } class ProductDto extends Dto { public function __construct( public string $name, public float $price, public ?CategoryDto $category = null, ) { } } // Create with nested DTO $product = ProductDto::fromArray([ 'name' => 'Laptop', 'price' => 999.99, 'category' => [ 'id' => 1, 'name' => 'Electronics', 'slug' => 'electronics', ], ]); // Nested DTO is automatically converted echo $product->category->name; // "Electronics"
Array of DTOs
For arrays of DTOs, use PHPDoc annotation:
use JOOservices\Dto\Dto; class ProductDto extends Dto { public function __construct( public string $name, public float $price, ) { } } class OrderDto extends Dto { /** * @var array<ProductDto> */ public array $items = []; public function __construct( public int $id, public float $total, ) { } } $order = OrderDto::fromArray([ 'id' => 1, 'total' => 199.99, 'items' => [ ['name' => 'Product 1', 'price' => 99.99], ['name' => 'Product 2', 'price' => 100.00], ], ]);
Property Access (Dto - Immutable)
$user = new UserDto('John Doe', 'john@example.com', 30); // Direct property access (read-only) echo $user->name; // "John Doe" // Check if property exists $user->hasProperty('email'); // true // Get property value $email = $user->getProperty('email'); // Create new instance with updated property (immutable update) $updatedUser = $user->with('age', 31); // Or update multiple properties $updatedUser = $user->with(['age' => 31, 'name' => 'Jane Doe']); // Get all property names $properties = $user->getPropertyNames(); // ['name', 'email', 'age']
Property Access (Data - Mutable)
use JOOservices\Dto\Data; class UserData extends Data { public function __construct( public string $name, public string $email, public ?int $age = null, ) { } } $user = new UserData('John Doe', 'john@example.com', 30); // Direct property access echo $user->name; // "John Doe" // Modify properties (mutable) $user->setProperty('age', 31); // Or use direct assignment $user->age = 31; $user->name = 'Jane Doe';
💡 Note:
DataandDtoare siblings (both extendAbstractDto), not parent-child. This design ensures both classes share common functionality throughSharedBaseTraitwhile maintaining distinct behavioral contracts.
Property Mapping (MapFrom)
Map input array keys to different property names:
use JOOservices\Dto\Attributes\MapFrom; use JOOservices\Dto\Dto; class PostDto extends Dto { public function __construct( #[MapFrom('post_title')] public string $title, #[MapFrom('user_name')] public string $author, public string $content, ) { } } // Input uses different key names $post = PostDto::fromArray([ 'post_title' => 'My Post', 'user_name' => 'John Doe', 'content' => 'Post content', ]); echo $post->title; // "My Post" echo $post->author; // "John Doe"
Validation Rules
Add validation rules to properties using attributes:
use JOOservices\Dto\Attributes\Required; use JOOservices\Dto\Attributes\Validation\Email; use JOOservices\Dto\Attributes\Validation\Min; use JOOservices\Dto\Attributes\Validation\Max; use JOOservices\Dto\Attributes\Validation\Regex; use JOOservices\Dto\Dto; class RegistrationDto extends Dto { public function __construct( #[Required] #[Email] public string $email, #[Required] #[Min(8)] #[Max(100)] public string $password, #[Regex('/^[A-Z]{2}\d{4}$/')] public ?string $code = null, ) { } } $dto = RegistrationDto::fromArray([ 'email' => 'user@example.com', 'password' => 'password123', ]); // Validate rules $errors = $dto->validateRules(); // Returns: [] (empty if valid) // Or validate and throw exception $dto->validateOrFail(); // Throws ValidationException if invalid
Output Transformers
Transform property values during serialization:
use DateTime; use JOOservices\Dto\Attributes\WithTransformer; use JOOservices\Dto\Dto; use JOOservices\Dto\Transformers\DateTimeTransformer; class EventDto extends Dto { public function __construct( #[WithTransformer(DateTimeTransformer::class, ['format' => 'Y-m-d'])] public DateTime $eventDate, public string $name, ) { } } $event = new EventDto(new DateTime('2024-01-15 14:30:00'), 'Conference'); $array = $event->toArray(); // ['eventDate' => '2024-01-15', 'name' => 'Conference']
Documentation
For detailed documentation, please refer to the Documentation Hub or browse by category:
🚀 Getting Started
- Installation Guide - Installation and setup instructions
- Getting Started - Quick start guide with examples
- Examples - Real-world examples and use cases
📖 Core Concepts
- Type Casting - Type casting system documentation
- Validation - Validation features and usage
- Attributes - Available attributes and usage
🔧 Advanced Topics
- Advanced Usage - Advanced features and patterns
- Pipeline Processing - Process DTOs through transformation pipelines
- Architecture - Package architecture and design
- API Reference - Complete API documentation
🤝 Contributing
- Contributing - Contributing guidelines
Requirements
- PHP 8.5 or higher
License
MIT
Changelog
See CHANGELOG.md for a detailed list of changes.
Version
Current Version: 1.0.0
Release Date: 2025-01-16
PHP Requirement: 8.5 or higher
Support
For issues, questions, or contributions, please contact:
- Developer: Viet VU
- Email: jooservices@gmail.com
- Website: jooservices.com
- Issues: GitHub Issues
- Jira: JOOdto Project
统计信息
- 总下载量: 1
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-01-09