讲师中心 微信公众号
AI工具推荐 视频效率加速

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

胖婷大大_8319

胖婷大大_8319

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

|

1272人浏览过

|

来源于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:

Laravel
Laravel

避免常见的Laravel错误:N+1查询、批量赋值、缓存陷阱及队列序列化陷阱。

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

示例:在物业管理系统中使用 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工具

更多
LibLibAI
LibLibAI Hot

一款AI视频创作工具,主要用于国内领先的AI创意平台,以海量模型、低门槛操作与“创作-分享-商业化”生态,让小白与专业创作者都能高效实现图文乃至视频创意表达,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

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

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

817

2024.04.09

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

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

815

2024.04.09

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

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

2408

2024.04.09

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

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

3381

2024.04.10

laravel入门教程
laravel入门教程

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

4750

2025.08.05

laravel实战教程
laravel实战教程

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

3176

2025.08.05

laravel面试题
laravel面试题

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

6069

2025.08.05

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

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

1356

2026.03.04

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

60

2026.09.23

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
如何安装 Composer
如何安装 Composer

共1课时 | 182人学习

Composer手册
Composer手册

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn