这可以帮助您轻松地从请求和数组中创建数据传输对象(DTO)

v1.0.7 2022-06-10 20:22 UTC

This package is auto-updated.

Last update: 2024-09-11 01:00:58 UTC


README

关于 DTO

这是一个 laravel 扩展包,通过简单的四个步骤,可以帮助您轻松地从请求和数组中创建数据传输对象(DTO)

  • 安装包
  • 通过命令行创建 DTO
  • 设置类的公共属性
  • 然后从请求或数组创建您的 DTO

DTO 使用请求或数组中的值设置属性,以便将此属性包(数据传输对象)传递到您的控制器、服务或操作中的函数

安装

使用 composer 安装包

    composer require mr-robertamoah/dto

配置

要开始配置此包的工作方式,首先使用以下命令发布配置文件

    php artisan vendor publish --tag=dto-config

此命令在配置文件夹中添加 dto.php 文件。以下显示了配置文件的键及其功能

  • folderName:这将帮助您使用除 DTO 之外的文件夹名称,这是默认设置
  • attachDTO:如果设置为 true,则每个创建的 DTO 名称都将以 DTO 结尾
  • forcePropertiesOnDTO:每次尝试将值设置到不存在的属性时,都会抛出异常。将此设置为 true 将动态在 DTO 对象上创建属性。
  • suppressPropertyNotFoundException:当设置为 true 时,不会抛出 DTOPropertyNotFoundException,而是返回对象。
  • suppressMethodNotFoundException:当设置为 true 时,不会抛出 DTOMeothdNotFoundException,而是返回对象。

用法

以下是使用 DTO 的分解方法

创建文件

您始终可以手动创建文件并扩展 BaseDTO 类,或使用 Laravel 的 artisan 命令。

    php artisan dto:make UserDTO

注意以下命令选项

  • --folderName:指向创建 DTO 的应用程序文件夹
  • --attachDTO:是否将 DTO 附加到文件和类名称中
  • --force:即使文件已存在,也强制创建文件。您还可以创建多个文件。
    php artisan dto:make UserDTO ImageDTO

设置属性

    class UserDTO extends BaseDTO
    {
        public $name;
        public $email;
    }

创建对象

从请求

    public function create(Illuminate\Http\Request $request)
    {
        $dto = UserDTO::fromRequest($request);
        //or
        $dto = UserDTO::new()->fromRequest($request);
    }

请注意,此请求应为 Illuminate\Http\Request 类型。

从数组

    public function create(Illuminate\Http\Request $request)
    {
        $data = [
            'name' => 'Robert Amoah',
            'email' => 'mr_robertamoah@yahoo.com',
        ];

        $dto = UserDTO::fromArray($data);
        //or
        $dto = UserDTO::new()->fromArray($data);
    }

传输数据

    public function create(Illuminate\Http\Request $request)
    {
        $dto = UserDTO::fromRequest($request);

        $user = UserService::createUser($dto);
    }

使用数据

    public function createUser(UserDTO $userDTO)
    {
        $user = User::create($userDTO->getFilledData());
    }

扩展创建方法

您可以使用 fromArrayExtensionfromRequestExtension 受保护方法分别扩展 fromArrayfromRequest 方法。这些方法将接收主创建方法传入的第一个参数(数组和要求)并必须返回相同的对象

    class UserDTO extends BaseDTO
    {
        public $name;
        public $email;
        public $date;

        protected function fromRequestExtenstion(Illuminate\Http\Request $request) : BaseDTO
        {
            return $this->date = new Carbon();
        }

        protected function fromArrayExtenstion(array $data) : BaseDTO
        {
            return $this->date = new Carbon();
        }
    }

属性

本节显示了 BaseDTO 类上可用的受保护属性,这些属性有助于您充分利用 dto 对象。

dtoDataKeys

如果您想获取除已填充属性之外的某些属性,则必须在此数组中指定这些属性

    // dto class
    class UserDTO extends BaseDTO
    {
        protected array $dtoDataKeys = [
            'name', 'email'
        ];
    }

    //in services, controller or actions
    public function createUser(UserDTO $userDTO)
    {
        $user = User::create($userDTO->getData());
    }

请注意,如果未将属性添加到 dtoDataKeys,则 getData 方法将返回空数组。如果像 getData(true) 一样将 true 传递给方法,则将返回已填充的属性作为数组。

dtoFileKeys

此属性帮助您设置从请求中检索文件的适当属性名称,以及通过使用 getFiles 方法轻松获取所有此类属性的数组。

    // dto class
    class UserDTO extends BaseDTO
    {
        protected array $dtoFileKeys = [
            'image1', 'image2'
        ];
    }

    // in service
    public function createUser(UserDTO $userDTO)
    {
        foreach($userDTO->getFiles() as $key => $file) {
            $file->save();
        }
    }

此外,可以通过在对象上分别调用setDataKeyssetFileKeys方法来动态设置dtoDataKeysdtoFileKeys。这些方法的追加版本会将额外的键添加到数组(dtoDataKeys和dtoFileKeys)中。

    UserDTO::new()
        ->setDataKeys(['name', 'email'])
        ->setFileKeys('image1, image2');

dtoExclude

如果不想在创建DTO时赋予该属性值,请将属性的名称添加到这个数组中。

    // dto class
    class UserDTO extends BaseDTO
    {
        protected array $dtoExclude = [
            'image1',
        ];
    }

dtoOnly

如果只想在创建DTO时赋予属性值,请将属性的名称添加到这个数组中。在下面的示例中,只有在创建DTO时,name和emails将被赋予值。

    // dto class
    class UserDTO extends BaseDTO
    {
        public $name;
        public $email;
        public $age;

        protected array $dtoExclude = [
            'name', 'email'
        ];
    }

请注意,一旦dtoOnly至少有一个条目,它将优先于dtoExclude

重要方法

这些方法允许您流畅地使用DTO,并充分利用其功能。

with[PropertyName]

这允许您调用以with开头并以属性名称结尾的公共方法。此方法的参数应该是您希望分配给属性的值。在值被分配后,此方法将返回DTO。

    // in service
    public function createUser(UserDTO $userDTO)
    {
        $userDTO = $userDTO->withName('James Coffie');

        $user = User::create($userDTO->getData()):
    }

addData

这允许您传递一个数组,该数组包含作为键的属性名称,这些键指向您希望分配给DTO的值。数组的键必须与您希望分配值的属性名称相匹配。在值被分配后,此方法将返回DTO。

    // in service
    public function createUser(UserDTO $userDTO)
    {
        $userDTO = $userDTO->addData([
            'name' => 'James Coffie',
            'email' => 'jamescoffie123@zigzag.org',
        ]);
        
        $user = User::create($userDTO->getData()):
    }

new

这是一个静态方法,允许您从DTO类创建一个新对象。

    // in controller
    public function create($request)
    {
        $userDTO = UserDTO::new();
        
        $user = UserService::create(
            $userDTO->setFileKeys(['image1', 'image2'])->fromRequest($request)
        ):
    }

forceProperties

当您尝试为DTO类中没有设置的属性赋值时,DTO将抛出DTOPropertyNotFound异常。当您在创建DTO之前使用此方法时,属性将动态设置。

    // in controller
    public function create($request)
    {
        $userDTO = UserDTO::new();
        
        $user = UserService::create(
            $userDTO->forceProperties()->fromRequest($request)
        ):
    }

异常

以下是由此包抛出的异常

  • DTOPropertyNotFound
  • DTOMethodNotFound
  • DTOWrongArgument
  • DTOFileAlreadyExists

请注意,DTOFileAlreadyExists只能在控制台抛出,而其他异常只能在使用DTO时抛出。您可以在配置文件中抑制DTOPropertyNotFoundDTOMethodNotFound异常。