让php开发更优雅-ThinkPHP篇

前言


随着开发经验的增加,也伴随团队开发的积累,规范开发显得越来越重要,本文给大家提供一些ThinkPHP框架开发API接口的进阶思路和经验,让大家开发更加统一规范,代码看起来更加优雅。

1.更多使用第三方库。团队开发的时候,各个人的开发经验和思考方式不同,也有一些思维局限性,可以多多使用第三方库,统一代码开发规范。

2.抛弃传统MVC模式,在结构上分出更新的结构分层,防止Controller过于臃肿和复杂,需要进行代码解耦。一般分为下面几层:

  • 数据验证层(Validate):负责验证请求参数,单独创建一个验证请求器,避免验证逻辑放在控制器中验证,例如:

    Laravel框架使用FormRequest Laravel中使用FormRequest进行表单验证及对验证异常进行自定义处理_51CTO博客_laravel 表单验证

  • 控制器层(Controller):负责接收参数、验证参数、调用各个模块的服务层(可以用事务包裹,用到其他服务的可以注入多个服务)、返回响应、返回视图等

  • 服务层(Service):负责具体的业务逻辑实现,将原本控制器的负责流程按模块拆分为一个个小的服务,方便给控制器层组合调用,一般不要跨模块调用服务,服务中可以调用本模块的仓库层方法

  • 仓库层(Repository):调用模型层封装一些负责的查询,方便服务层调用,一般负责只查询本模块的内容

  • 模型层(Model):只包含默认的表属性(表名、字段等)和联表关系

  • (更多层级)

环境搭建


  • 验证器(Validate)

    ThinkPHP5.1及以上不需要使用第三方验证器扩展,使用自带的验证器即可,官方文档:验证器 - ThinkPHP官方手册

    ThinkPHP5.0没有提供命令行创建验证器,可以使用第三方扩展包实现:Thinkphp5.0命令行创建验证器validate类-CSDN博客

  • 服务层(Service)

    使用第三方扩展包增加命令行功能:Thinkphp命令行创建Service(服务层)扩展包-CSDN博客

  • 仓库层(Repository)

    使用第三方扩展包增加命令行功能:Thinkphp命令行创建repository和transform层扩展包-CSDN博客

  • 统一响应数据结构

    增加自定义trait:Thinkphp封装统一响应-CSDN博客

开发示例


用Think5.1框架以用户注册流程为例

  • 控制器(Controller)

    创建空白的用户控制器

     php think make:controller api/User --plain
    

    控制器校验请求参数后调用不同 service 进行业务处理,调用转换器将数据返回,示例:

    <?php
    
    namespace app\api\controller;
    
    use app\common\service\UserService;
    use app\common\transform\UserTransform;
    use app\common\validate\UserValidate;
    use think\App;
    use think\Db;
    
    class User extends Controller
    {
        protected $service;
    
        public function __construct(App $app = null, UserService $service)
        {
            parent::__construct($app);
            $this->service = $service;
        }
    
        /**
         * 获取用户信息
         */
        public function info(UserTransform $transform)
        {
            $userInfo = $this->service->getUserById(1);
            $this->success($transform->userInfo($userInfo)); //使用转化器
        }
    
        /**
         * 用户注册
         *
         * @param UserValidate $validate 用户验证器
         * @param SmsService $smsService 短信服务
         * @return void
         */
        public function register(UserValidate $validate, SmsService $smsService){
            //参数验证
            $data = $this->request->param();
            if (!$validate->scene('register')->check($data)) {
                $this->fail($validate->getError()); // 继承的Controller里use trait CustomResponse,所以这里可以直接使用fail方法;
            }
    
            //短信验证码验证
            if (!$smsService->check($data['mobile'], 'register', $data['sms_code'])){
                $this->fail('验证码错误');
            }
    
            Db::startTrans();
            try{
                //新增用户
                $this->userService->addUser($data);
    
                //绑定推荐人...
    
                //其他服务操作...
    
                // 提交事务
                Db::commit();
            }catch (\Exception $e){
                // 回滚事务
                Db::rollback();
    
                $this->error($e->getMessage());
            }
    
            $this->ok('注册成功');
        }
    }
    
  • 验证器(Validate)

    创建验证器

    php think make:validate UserValidate
    

    在验证器中添加验证规则、提示信息和验证场景

    <?php
    
    namespace app\common\validate;
    
    use think\Validate;
    
    class UserValidate extends Validate
    {
        /**
         * 定义验证规则
         * 格式:'字段名'	=>	['规则1','规则2'...]
         *
         * @var array
         */
    	protected $rule = [
            'mobile' => 'require|regex:/^1[3-9]\d{9}$/',
            'password' => 'require|min:6',
            'sms_code' => 'require|length:6|number',
        ];
    
        /**
         * 定义错误信息
         * 格式:'字段名.规则名'	=>	'错误信息'
         *
         * @var array
         */
        protected $message = [
            'mobile.require' => '手机号码必填',
            'mobile.regex' => '手机号码格式不正确',
            'password.require' => '密码不能为空',
            'sms_code.require' => '短信验证码不能为空',
            'sms_code.length' => '请输入6位短信验证码',
        ];
    
        /**
         * 定义验证场景和对应的验证字段
         */
        protected $scene = [
            //注册
            'register' => [
                'mobile',
                'password',
                'sms_code'
            ],
    
            //登录
            'login' => [
                'mobile',
                'password'
            ],
        ];
    }
    
  • 模型(Model)

    创建模型

    php think make:model User
    

    User模型的默认内容为

    <?php
    
    namespace app\common\model;
    
    use think\Model;
    
    class User extends Model
    {
        //
    }
    
  • 服务层(Service)

    创建服务

    php think make:service UserService
    

    生成的UserService自动绑定对应的仓库

    <?php
    
    namespace app\common\service;
    
    use app\common\repository\UserRepository;
    
    class UserService
    {
        /**
         * 绑定仓库
         * @var UserRepository
         */
        protected $repository;
    
        public function __construct(UserRepository $repository)
        {
            $this->repository = $repository;
        }
    
        /**
         * 添加用户
         */
        public function addUser($data)
        {
            //密码加密、用户数据处理
            ...
                
            //创建用户
            $this->repository->create($data);
        }
    
        /**
         * 查找用户
         * @param $id
         * @return \Illuminate\Database\Eloquent\Builder
         */
        public function getUserById($id)
        {
            return $this->repository->find($id);
        }
    }
    
  • 仓库层(Repository)

    创建仓库

    php think make:repository UserRepository
    

    生成的UserRepository自动绑定对应的模型,里面定义一些联表等复杂查询操作

    <?php
    
    namespace app\common\repository;
    
    use think\App;
    use app\common\model\User;
    use Jian1098\TpRepository\Repository;
    
    /**
     * Class UserRepository
     */
    class UserRepository extends Repository
    {
        protected $model;
    
        public function __construct()
        {
            parent::__construct(new App());
            //绑定模型
            $this->model = new User();
        }
    
    }
    
  • 转换器

    转换器用于转换查询到的数据结果接口,可用可不用,如果需要对多个字段进行处理,使用转换器比较美观优雅

    创建转换器

    php think make:transform UserTransform
    

    默认内容如下

    <?php
    
    namespace app\common\transform;
    
    use Jian1098\TpRepository\Command\Transform;
    
    class UserTransform extends Transform
    {
        //用户信息
        public function userInfo($items)
        {
            return [
                'user_id'       => $items['id'],
                'user_name'     => $items['nickname'],
            ];
        }
    }
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/577859.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux系统编程】第八弹---权限管理操作(中)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、修改文件权限的做法(二) 2、文件类型 3、可执行权限 4、创建文件/目录的默认权限 4.1、权限掩码 总结 前面一弹我们学…

CH4INRULZ-v1靶机练习实践报告

CH4INRULZ-v1靶机练习实践报告 1 安装靶机 靶机是.ova文件&#xff0c;需要用VirtualBox打开&#xff0c;但我习惯于使用VMWare,因此修改靶机文件&#xff0c;使其适用于VMWare打开。 解压ova文件&#xff0c;得到.ovf文件和.vmdk文件。直接用VMWare打开.ovf文件即可。 2 夺…

社区新零售:重构邻里生活圈,赋能美好未来

新时代的邻里脉动 在城市的肌理中&#xff0c;社区作为生活的基本单元&#xff0c;正经历一场由新零售引领的深刻变革。社区新零售&#xff0c;以其独特的商业模式、创新的技术手段和以人为本的服务理念&#xff0c;重新定义了社区商业的边界&#xff0c;重构了邻里生活的形态…

[C++ QT项目实战]----C++ QT系统实现多线程通信

前言 在C QT中&#xff0c;多线程通信原理主要涉及到信号与槽机制和事件循环机制。 1、信号与槽机制&#xff1a; 在QT中&#xff0c;信号与槽是一种用于对象间通信的机制。对象可以通过发送信号来通知其他对象&#xff0c;其他对象通过连接槽来接收信号并进行相应的处…

软件物料清单(SBOM)生成指南 .pdf

如今软件安全攻击技术手段不断升级&#xff0c;攻击数量显著增长。尤其是针对软件供应链的安全攻击&#xff0c;具有高隐秘性、追溯难的特点&#xff0c;对企业软件安全威胁极大。 同时&#xff0c;软件本身也在不断地更新迭代&#xff0c;软件内部成分安全性在持续变化浮动。…

web题目实操 5(备份文件和关于MD5($pass,true)注入的学习)

1.[ACTF2020 新生赛]BackupFile &#xff08;1&#xff09;打开页面后根据提示是备份文件 &#xff08;2&#xff09;查看源码发现啥都没有 &#xff08;3&#xff09;这里啊直接用工具扫描&#xff0c;可以扫描到一个文件名为&#xff1a;/index.php.bak的文件 &#xff08;…

json解析大全

JSON解析案例1 将String转为JSONObject JSONObject res JSONObject.parseObject(result);获取documents JSONArray array res.getJSONObject("result").getJSONArray("documents");遍历JSONArray for (int i 0; i < array.size(); i) {JSONObject…

IDEA pom.xml依赖警告

IDEA中&#xff0c;有时 pom.xml 中会出现如下提示&#xff1a; IDEA 2022.1 升级了检测易受攻击的 Maven 和 Gradle 依赖项&#xff0c;并建议修正&#xff0c;通过插件 Package Checker 捆绑到 IDE 中。 这并不是引用错误&#xff0c;不用担心。如果实在强迫症不想看到这个提…

稳态视觉诱发电位 (SSVEP) 分类学习系列 (4) :Temporal-Spatial Transformer

稳态视觉诱发电位分类学习系列:Temporal-Spatial Transformer 0. 引言1. 主要贡献2. 提出的方法2.1 解码的主要步骤2.2 网络的主要结构 3. 结果和讨论3.1 在两个数据集下的分类效果3.2 与基线模型的比较3.3 消融实验3.4 t-SNE 可视化 4. 总结欢迎来稿 论文地址&#xff1a;http…

Hive——DDL(Data Definition Language)数据定义语句用法详解

1.数据库操作 1.1创建数据库 CREATE DATABASE [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPERTIES (property_nameproperty_value, ...)];IF NOT EXISTS&#xff1a;可选参数&#xff0c;表示如果数据库已经存在&#xff0c…

软考-系统分析师-精要2

5、可行性分类 经济可行性&#xff1a;成本收益分析&#xff0c;包括建设成本、运行成本和项目建设后可能的经济收益。 技术可行性&#xff1a;技术风险分析&#xff0c;现有的技术能否支持系统目标的实现&#xff0c;现有资源&#xff08;员工&#xff0c;技术积累&#xff0…

GEM TSU Interface Details and IEEE 1588 Support

摘要&#xff1a;Xilinx ZNYQ ULTRASCALE MPSOC的GEM和1588的使用 对于FPGA来说&#xff0c;只需要勾选一些znyq的配置就行了&#xff0c;其余的都是软件的工作&#xff1b; 所有配置都勾选之后&#xff0c;最终会露出来的接口如下&#xff1a; GEM需要勾选的配置如下&#xf…

泰坦尼克号乘客生存情况预测分析2

泰坦尼克号乘客生存情况预测分析1 泰坦尼克号乘客生存情况预测分析2 泰坦尼克号乘客生存情况预测分析3 泰坦尼克号乘客生存情况预测分析总 背景描述 Titanic数据集在数据分析领域是十分经典的数据集&#xff0c;非常适合刚入门的小伙伴进行学习&#xff01; 泰坦尼克号轮船的…

AI新闻速递:揭秘本周科技界最热的AI创新与发展

兄弟朋友们&#xff0c;本周的AI领域又迎来了一系列激动人心的进展。在这个快速变化的时代&#xff0c;不会利用AI的人&#xff0c;就像在数字化高速公路上步行的旅行者&#xff0c;眼看着同行者驾驶着智能汽车绝尘而去&#xff0c;而自己却束手无策。 1. Adobe Firefly 3&…

【基础算法总结】双指针算法二

双指针 1.有效三角形的个数2.和为S的两个数字3.和为S的两个数字4.四数之和 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1.有效三角形的个数…

深度学习运算:CUDA 编程简介

一、说明 如今&#xff0c;当我们谈论深度学习时&#xff0c;通常会将其实现与利用 GPU 来提高性能联系起来。GPU&#xff08;图形处理单元&#xff09;最初设计用于加速图像、2D 和 3D 图形的渲染。然而&#xff0c;由于它们能够执行许多并行操作&#xff0c;因此它们的实用性…

Python游戏工具包pygame

当你涉及游戏开发时&#xff0c;Pygame是一个强大的工具包&#xff0c;它提供了一系列功能丰富的模块和工具&#xff0c;让你可以轻松地创建各种类型的游戏。在本文中&#xff0c;我将介绍Pygame的依赖以及其详细属性&#xff0c;同时提供一些示例代码来说明其用法。 目录 一…

Github 2024-04-27 开源项目日报 Top9

根据Github Trendings的统计,今日(2024-04-27统计)共有9个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目6TypeScript项目2C++项目1JavaScript项目1Open-Sora: 构建自己的视频生成模型 创建周期:17 天开发语言:Python协议类型:Apache Lic…

嵌入式Linux学习——Linux常用命令(上)

Linux命令行介绍 Linux Shell 简介 Shell 的意思是“外壳”&#xff0c;在 Linux 中它是一个程序&#xff0c;比如/bin/sh、/bin/bash 等。它负责接收用户的输入&#xff0c;根据用户的输入找到其他程序并运行。比如我们输入“ ls”并回车时&#xff0c; shell 程序找到“ ls…

TinyML之Hello world----基于Arduino Nano 33 BLE Sense Rev2的呼吸灯

早期版本的Hello World 这应该是一个逼格比较高的呼吸灯了&#xff0c;用ML来实现呼吸灯功能&#xff0c;之前已经有大佬发过类似的文章&#xff1a;https://blog.csdn.net/weixin_45116099/article/details/126310816 当前版本的Hello World 这是一个ML的入门例程&#xff…
最新文章