0

0

探索数据传输对象 (DTO) 的优势以及 PHP 只读类如何提升您的 Laravel 代码

WBOY

WBOY

发布时间:2024-07-30 09:19:13

|

1252人浏览过

|

来源于dev.to

转载

探索数据传输对象 (dto) 的优势以及 php 只读类如何提升您的 laravel 代码

在现代 web 应用程序开发中,高效、安全地管理和传输数据至关重要。对此过程有显着帮助的一种设计模式是数据传输对象 (dto)。这篇文章将深入探讨使用 dto 的优势,特别是在 laravel 应用程序中,并展示 php 8.2 只读类如何进一步增强其优势。

什么是数据传输对象 (dto)?

数据传输对象(dto)是一个简单的对象,旨在在进程或系统之间传输数据。与典型的模型或实体不同,dto 不受业务逻辑的影响。它们封装数据,提供一种清晰且结构化的方式在应用程序的不同层或不同系统之间传输信息。

dto模式

dto 模式用于在软件应用程序内的不同子系统之间传输数据。使用 dto 的主要目标是最大限度地减少方法调用的数量、聚合必要的数据并提供结构化方法来管理数据转换和验证。

使用 dto 的好处

  • 关注点分离: dto 将业务逻辑与数据表示分离,从而产生更清晰、更易于维护、更易于理解的代码。

    立即学习PHP免费学习笔记(深入)”;

  • 数据验证: dto 允许在其他应用程序层处理数据之前对数据进行验证,确保仅使用有效数据。

  • 一致性: 通过提供一致的数据传输结构,dto 简化了来自各种来源的数据的管理和处理。

  • 安全: dto 可以通过控制哪些数据可访问和可修改来保护您的应用程序免受未经授权的数据操纵。

  • 测试: 由于 dto 是没有嵌入业务逻辑的简单对象,因此它们更容易模拟和测试。

  • 转换: dto 有助于将数据转换为不同应用层所需的格式。

  • 不变性: dto 通常提倡不变性,这意味着一旦创建,它们的状态就无法更改。此功能带来了几个优点:

    • 可预测性: 不可变对象是可预测的并且更容易推理,因为它们的状态在创建后保持不变。
    • 线程安全: 不变性本质上支持线程安全,简化并发处理。
    • 调试: 使用不可变对象进行调试更容易,因为它们的状态保证在整个生命周期中保持不变。

php 8.2 和只读类

在 php 8.2 中,只读类的引入增强了 dto 的使用。只读类无需将属性显式定义为只读,从而简化了 dto 实现。以下是 php 8.2 的只读类如何改进 dto:

一点PPT
一点PPT

一句话生成专业PPT,AI自动排版配图

下载
  • 简化代码:只读类自动使属性不可变,减少样板代码并提高清晰度。
  • 增强的安全性:通过确保属性一旦设置就无法修改,只读类增强了数据完整性和安全性。
  • 提高可维护性: 使用只读类可以生成更干净、更易于维护的代码,因为数据的不变性是由语言本身强制执行的。

示例:在物业管理系统中使用 dto

让我们考虑一个属性管理系统,其中属性可以来自各种来源,例如 api 和 csv 导入。我们可以使用 dto 创建属性模型、订阅、资产等,确保数据在整个应用程序中一致并经过验证。

定义 propertydto

首先,我们定义一个propertydto类:

app/dto/propertydto.php

namespace app\dto;

/**
 * class propertydto
 *
 * represents a data transfer object for property data.
 */
readonly class propertydto extends abstractdto
{
    /**
     * the name of the property.
     *
     * @var string
     */
    public string $name;

    /**
     * the address of the property.
     *
     * @var string
     */
    public string $address;

    /**
     * the price of the property.
     *
     * @var float
     */
    public float $price;

    /**
     * the subscription status of the property, if applicable.
     *
     * @var string|null
     */
    public ?string $subscription;

    /**
     * the list of assets associated with the property.
     *
     * @var array|null
     */
    public ?array $assets;

    /**
     * set the properties from a model instance.
     *
     * @param $model the model instance.
     * @return $this
     */
    public function setfrommodel($model): self
    {
        $this->name = $model->name;
        $this->address = $model->address;
        $this->price = $model->price;
        $this->subscription = $model->subscription;
        $this->assets = $model->assets;

        return $this;
    }

    /**
     * set the properties from api data.
     *
     * @param array $data the api data.
     * @return $this
     */
    public function setfromapi(array $data): self
    {
        $this->name = $data['property_name'];
        $this->address = $data['property_address'];
        $this->price = $data['property_price'];
        $this->subscription = $data['subscription'] ?? null;
        $this->assets = $data['assets'] ?? null;

        return $this;
    }

    /**
     * set the properties from csv data.
     *
     * @param array $data the csv data.
     * @return $this
     */
    public function setfromcsv(array $data): self
    {
        $this->name = $data[0];
        $this->address = $data[1];
        $this->price = (float) $data[2];
        $this->subscription = $data[3] ?? null;
        $this->assets = explode(',', $data[4] ?? '');

        return $this;
    }
}
使用 propertydto

以下是如何使用 propertydto 处理来自不同来源的属性:

// from a model
$model = property::find(1);
$propertydto = (new propertydto([]))->setfrommodel($model);

// from an api
$apidata = [
    'property_name' => 'beautiful house',
    'property_address' => '1234 elm street',
    'property_price' => 450000,
    'subscription' => 'premium',
    'assets' => ['pool', 'garden']
];
$propertydto = (new propertydto([]))->setfromapi($apidata);

// from a csv
$csvdata = ['beautiful house', '1234 elm street', 450000, 'premium', 'pool,garden'];
$propertydto = (new propertydto([]))->setfromcsv($csvdata);

// convert to array
$arraydata = $propertydto->toarray();

// convert to json
$jsondata = $propertydto->tojson();

概括

数据传输对象 (dto) 通过确保数据一致性、验证和关注点分离,在 laravel 应用程序中提供了众多优势。通过实施 dto,您可以使应用程序更易于维护、更安全且更易于测试。在物业管理系统中,dto 有助于高效处理来自各种来源(例如 api 和 csv 导入)的数据,确保您的业务逻辑保持干净并专注于处理经过验证的数据。

此外,在 dto 中采用不变性可以增强可预测性、线程安全性并简化调试。

使用抽象类扩展 dto 以保持一致性

为了简化 dto 的创建并促进代码重用,我们可以使用抽象类或基类。这种方法允许我们在抽象类中定义通用的方法和属性,并针对特定的数据源扩展它。

定义 abstractdto

app/dto/abstractdto.php

namespace App\DTO;

/**
 * AbstractDTO
 *
 * An abstract base class for Data Transfer Objects (DTOs).
 * Provides common methods and properties for DTO implementations.
 */
abstract class AbstractDTO
{
    /**
     * AbstractDTO constructor.
     *
     * Initialises the DTO with data from an associative array.
     *
     * @param array $data The data array to initialize the DTO.
     */
    public function __construct(array $data)
    {
        $this->setFromArray($data);
    }

    /**
     * Set the properties of the DTO from a model instance.
     *
     * @param $model The model instance from which to populate the DTO.
     * @return $this
     */
    abstract public function setFromModel($model): self;

    /**
     * Set the properties of the DTO from API data.
     *
     * @param array $data The data array from the API.
     * @return $this
     */
    abstract public function setFromAPI(array $data): self;

    /**
     * Set the properties of the DTO from CSV data.
     *
     * @param array $data The data array from the CSV.
     * @return $this
     */
    abstract public function setFromCSV(array $data): self;

    /**
     * Convert the DTO to an associative array.
     *
     * @return array The DTO data as an associative array.
     */
    public function toArray(): array
    {
        $properties = get_object_vars($this);
        return array_filter($properties, function ($property) {
            return $property !== null;
        });
    }

    /**
     * Convert the DTO to a JSON string.
     *
     * @return string The DTO data as a JSON string.
     */
    public function toJson(): string
    {
        return json_encode($this->toArray());
    }

    /**
     * Set the properties of the DTO from an associative array.
     *
     * @param array $data The data array to populate the DTO.
     */
    protected function setFromArray(array $data): void
    {
        foreach ($data as $key => $value) {
            if (property_exists($this, $key)) {
                $this->$key = $value;
            }
        }
    }
}

最后的想法

为 dto 使用抽象类或基类不仅可以确保不同 dto 实现之间的一致性,还可以促进代码重用和可维护性。通过在抽象类中定义通用方法和属性,您可以创建一种结构化且有效的方法来管理应用程序内的数据传输。这种方法非常符合干净代码的原则,有助于构建可扩展且健壮的应用程序。

这是一个修改后的短语,其中包括号召性用语:

“通过一起利用 dto 和抽象类,您可以改进 laravel 应用程序的设计,改进数据管理方式并确保更有组织和高效的数据流。如果您想使用特征和接口进一步封装和增强您的 dto,请探索我们的关于使用特征、接口和抽象类增强面向对象设计的指南。”

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

340

2024.04.09

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

293

2024.04.09

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

773

2024.04.09

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

385

2024.04.10

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

141

2025.08.05

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

85

2025.08.05

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

80

2025.08.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

540

2026.03.04

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Laravel---API接口
Laravel---API接口

共7课时 | 0.7万人学习

PHP自制框架
PHP自制框架

共8课时 | 0.6万人学习

PHP面向对象基础课程(更新中)
PHP面向对象基础课程(更新中)

共12课时 | 0.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号