cerbero/laravel-dto
Composer 安装命令:
composer require cerbero/laravel-dto
包简介
Data Transfer Object (DTO) for Laravel
README 文档
README
Laravel DTO integrates DTO, a package inspired by Lachlan Krautz' excellent data-transfer-object, with the functionalities of Laravel.
A data transfer object (DTO) is an object that carries data between processes. DTO does not have any behaviour except for storage, retrieval, serialization and deserialization of its own data. DTOs are simple objects that should not contain any business logic but rather be used for transferring data.
Below are explained the advantages brought by this package in a Laravel application. In order to discover all the features of DTO, please refer to the full DTO documentation.
Install
Via Composer:
composer require cerbero/laravel-dto
To customize some aspects of this package, the config/dto.php file can optionally be generated via:
php artisan vendor:publish --tag=dto
Usage
- Generate DTOs
- Instantiate a DTO
- Resolve a DTO
- Convert into DTO
- Convert into array
- Listen to events
- Support for macros
- DTO debugging
Generate DTOs
DTOs for Eloquent models can be automatically generated by running the following Artisan command:
php artisan make:dto App/User
The database table of the specified model is scanned to populate the DTO properties. Furthermore, if the model has relationships, a DTO is also generated for each related model. For example, if our User model looks like:
class User extends Model { public function posts() { return $this->hasMany('App\Post'); } }
The DTOs App\Dtos\UserData and App\Dtos\PostData are generated like so:
use Cerbero\LaravelDto\Dto; use Carbon\Carbon; use const Cerbero\Dto\PARTIAL; use const Cerbero\Dto\IGNORE_UNKNOWN_PROPERTIES; /** * The data transfer object for the User model. * * @property int $id * @property string $name * @property Carbon $createdAt * @property Carbon $updatedAt * @property PostData[] $posts */ class UserData extends Dto { /** * The default flags. * * @var int */ protected static $defaultFlags = PARTIAL | IGNORE_UNKNOWN_PROPERTIES; } /** * The data transfer object for the Post model. * * @property int $id * @property string $content * @property int $userId * @property Carbon $createdAt * @property Carbon $updatedAt * @property UserData $user */ class PostData extends Dto { /** * The default flags. * * @var int */ protected static $defaultFlags = PARTIAL | IGNORE_UNKNOWN_PROPERTIES; }
By default, DTOs are generated in the Dtos directory which is created where models are. For example the DTO for App\User is generated as App\Dtos\UserData and the DTO for App\Users\User is generated as App\Users\Dtos\UserData.
To change either the location or the suffix Data of generated DTOs, we can create a DTO qualifier by implementing the interface DtoQualifierContract and replace the default qualifier in config/dto.php. The example below qualifies a DTO in the directory of the model and adds the suffix Dto:
use Cerbero\LaravelDto\DtoQualifierContract; class MyDtoQualifier implements DtoQualifierContract { public function qualify(string $model): string { return $model . 'Dto'; } } // in config/dto.php return [ 'qualifier' => MyDtoQualifier::class, ];
Finally, if a model has already its own DTO generated, we can overwrite it with the option --force or -f:
php artisan make:dto App/User --force
Instantiate a DTO
In addition to the traditional ways to instantiate a DTO, Laravel DTO provides handy methods to create a new instance of DTO from HTTP requests, Eloquent models or other common interfaces present in Laravel.
For example UserData can be instantiated from an HTTP request by calling the method fromRequest():
use App\Dtos\UserData; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class UserController extends Controller { public function store(Request $request) { $dto = UserData::fromRequest($request); } }
The request passed to the method fromRequest() is optional: if not provided, the current application request is used to instantiate UserData.
By default the flags PARTIAL and IGNORE_UNKNOWN_PROPERTIES are applied to the DTO when it is instantiated from a request. Additional flags can be passed as second parameter to further customize the behaviour of the DTO.
To instantiate a DTO from an Eloquent model, we can call the method fromModel():
$user = new User(['name' => 'Phil']); $dto = UserData::fromModel($user);
The flags PARTIAL, IGNORE_UNKNOWN_PROPERTIES and CAST_PRIMITIVES are applied to the DTO when it is instantiated from a model. Additional flags can be passed as second parameter.
Finally, the method from() instantiates a DTO from several interfaces (specific to Laravel or not), including:
Illuminate\Support\EnumerableIlluminate\Contracts\Support\ArrayableIlluminate\Contracts\Support\JsonableJsonSerializableTraversable- any value that can be casted into an array
In this case no flags are applied by default, but they can still be passed as second parameter.
Resolve a DTO
As long as PARTIAL is set in the default flags of a DTO, such DTO can be automatically resolved by the Laravel IoC container with the data carried by the current application request:
use App\Dtos\UserData; use App\Http\Controllers\Controller; class UserController extends Controller { public function store(UserData $dto) { // ... } }
Convert into DTO
Another way to get an instance of DTO from different objects is letting them use the trait TurnsIntoDto and call the method toDto():
use Cerbero\LaravelDto\Traits\TurnsIntoDto; class StoreUserRequest extends Request { use TurnsIntoDto; } class User extends Model { use TurnsIntoDto; protected $dtoClass = UserData::class; } class Example { use TurnsIntoDto; protected function getDtoClass(): ?string { return $condition ? UserData::class : OtherDto::class; } } $dto = $request->toDto(UserData::class, MUTABLE); $dto = $user->toDto(CAST_PRIMITIVES); $dto = $example->toDto();
Classes using the trait can specify the DTO to turn into by:
- passing the DTO class name as first parameter of the method
toDto() - defining the property
$dtoClass - overriding the method
getDtoClass()if custom logic is needed
Flags can optionally be passed as second parameter, or first parameter if the DTO class is already defined in the class using the trait. When models turn into DTOs, the flag CAST_PRIMITIVES is added to help casting values if casts are not defined on the Eloquent models.
Convert into array
By default Laravel DTO registers a value converter for Carbon instances. When a DTO is converted into array, all its Carbon objects are turned into an atom string and then converted back into Carbon instances when a new DTO is instantiated:
$dto = UserData::make(['created_at' => '2000-01-01']); $dto->createdAt; // Carbon instance $data = $dto->toArray(); // ['created_at' => '2000-01-01T00:00:00+00:00'] $dto = UserData::make($data); $dto->createdAt; // Carbon instance
Conversions can be added or removed in the config/dto.php file, specifically via the key conversions:
use Carbon\Carbon; use Cerbero\LaravelDto\Manipulators\CarbonConverter; return [ 'conversions' => [ Carbon::class => CarbonConverter::class, ], ];
Listen to events
The only feature added by this package to listeners is the ability to resolve dependencies via the Laravel IoC container. Dependencies can be injected into listeners constructor to be automatically resolved.
Listeners can be added or removed in the config/dto.php file, specifically via the key listeners:
return [ 'listeners' => [ UserData::class => UserDataListener::class, ], ];
Define flags globally
Sometimes we may want all our DTOs to share the same flags, an example might be the need to always work with mutable DTOs. An easy way to accomplish that is defining such flags in the config/dto.php file:
return [ 'flags' => MUTABLE, ];
Support for macros
In case we need to add functionalities to all DTOs, an option might be using macros. Please refer to the Laravel documentation to see an example of how to register a macro.
DTO debugging
When using the helpers dump() or dd(), only DTOs data will be shown instead of all the underlying architecture that makes the package work:
dd($dto); // only DTO data is shown: App\Dtos\UserData {#3224 +name: "Phil" }
Change log
Please see CHANGELOG for more information on what has changed recently.
Testing
composer test
Contributing
Please see CONTRIBUTING and CODE_OF_CONDUCT for details.
Security
If you discover any security related issues, please email andrea.marco.sartori@gmail.com instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.
cerbero/laravel-dto 适用场景与选型建议
cerbero/laravel-dto 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 13.72k 次下载、GitHub Stars 达 58, 最近一次更新时间为 2020 年 04 月 01 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「laravel」 「dto」 「Data Transfer Object」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 cerbero/laravel-dto 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 cerbero/laravel-dto 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 cerbero/laravel-dto 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Shoot aims to make providing data to your templates more manageable
Adds the EDTF data type to Wikibase
PHP library for the MUMSYS project
A simple library that allows transform any kind of data to native php data or whatever
Data transfer objects
Data provider for yii2
统计信息
- 总下载量: 13.72k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 59
- 点击次数: 21
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2020-04-01