0

0

解决方案:处理laravel返回值响应

藏色散人

藏色散人

发布时间:2021-07-05 16:57:41

|

3230人浏览过

|

来源于learnku

转载

下面由laravel教程栏目给大家介绍一种对于laravel异常作为返回的解决方式,希望对需要的朋友有所帮助!

  • 我们假定一个场景,用户注册, 需要参数

    参数名 解释 类型 是否必填
    mobile 用户手机号码 字符串 必填
    sms_code 短信验证码 整数 必填
    password 用户密码 字符串 用户密码
    re_password 重复用户密码 整数 重复用户密码
  • 以下列举会出现的问题情况

    1. 用户短信不匹配
    2. 用户短信类型错误
    3. 用户密码不相同
    4. 手机号已经使用过 直接登录即可
    5. 用户密码类型不符合要求
    6. 短信验证码不能为空
    7. 手机号码不能为空
    8. 两个密码都不能为空
  • 现在已知会复用的场景有  会在别的业务内有相同错误的类型 (具体业务不做赘述,业务不同,理解不同)

    1. 短信验证 checkSms 验证短信验证码是否正确 类型是否匹配
    2. 修改密码  提示密码类型错误等场景
  • 这里假定大家都不是大佬 业务有藕合 处理方案如下 (以下代码仅在checkSms下进行)

    1. 在checkSms函数里面直接
      //第一次写文档 不会用markdown 你也可以用 response出去  这样浅显易懂exit(json_encode(['code'=>-1,'msg'=>'短信验证码错误']));
    2. 每处都做判断
      if (false === checkSms($mobile,$code,$type)){
        exit(json_encode(['code'=>-1,'msg'=>'短信验证码错误']));}
    3. 看看我的方式 (这句要怎么加粗啊)
  • 已知你有三套业务 且每套业务包含N个子模块 (别杠微服务/跨语言等,杠就是你赢 /狗头)

    1. 现在出了问题 前端告诉你 code=-1 message=>’系统错误 || 需要登录 || 商品查询失败 || 短信失败 等各种错误信息 ‘
      你什么心情????????????? 开始到处找,这个message在哪, 谁写的 ,什么时候写的,到底是哪个等
    2. 业务有藕合, 你在你的业务里面用的某一个service(仅做伪例子)内的action 发现抛出了一个你不清楚的异常,你去问,贴日志
      结果必然是  你找的人去执行我上面说的那条,依次递归. 直到
       Fatal error: Allowed memory size of 1073741824 bytes exhausted (tried to allocate 9216 bytes) in your problem

      我就找不到在哪,我就是懵 日常维护老项目的同学岂不是人都没了… 为什么大家都是接盘,我缺过得这么难
  • 与其到处去找不如直接告诉我是怎么回事,但是你又很难保证大家写的错误信息内容都是一样的

    1. 首先我们明白一个道理 你写代码最害怕的是什么 是bug吗? 不是
      是这个

      你问我错哪了?  我怎么知道!!!!! 我就知道肯定报错了 抛出异常了 ,程序停了啊!!!

    2. ok 那么我们知道了一个道理,当程序抛出异常的时候,项目就会停掉.
       同时我们也明白了一件事 叫做:

    3. 假定我们有一个业务模块叫做 User 里面包含了一个控制器叫做 AuthController
      内部需要完成一个login的行为

       <?php 
       namespace AppHttpControllersApplicationAuth;
      
       use AppHttpControllersController;
       use AppHttpRequestsApplicationAuthLoginRequest;
       use IlluminateHttpJsonResponse;
      
       class AuthController extends Controller
       {
           //
           public function index(LoginRequest $loginRequest): JsonResponse     {
               $data = $loginRequest->all();
               //todo 验证是否登录成功
      
               //todo 登录成功之后需要从返回里面获取token 和 userInfo
      
               //todo 记录日志等行为
      
               //todo 返回前端 
               return $this->success('登陆成功', compact('token', 'user'));
           }
       }
      1. 一般会怎么做
        1. if (!empty(login($username,$password))){ //todo 登录成功 //tonext}
      2. 一旦出错 怎么办?????? 开始
          if(1){
              if(1){
                  if(1){
                      if(1){
                      //建议这里直接用来测光速到底是多少 ,因为需求是无限长的
                      //并且你知道到底是什么问题,什么业务返回来的,到底的意思是什么嘛? (突然成为派大星 )
                      }
                  }
              }
          }
      3. 如果你觉得 上面这个方案或者类似这个方案很棒,那我收回刚才那张图
  • 我们上面已知程序抛出异常就会停掉,除非你继续catch 然后抛什么出来??????怕不是万能交税
      1.我们设计让我们的程序听话,怎么听话,让他犯错自己会停,还会告诉你怎么回事
      2.怎么实现,这么做的意义是什么
      3.如何实现,这样做有什么别的意义没
      4.性能损耗问题

  • 回答问题
     1.你是开发,程序是你的 你必须说什么让他听什么
     2.此处仅做流程展示,最后会直接贴代码加注释,如果没耐心可以直接翻最后 创建异常应该都ok吧,不ok 就去看文档 你可以停在这了

    一点PPT
    一点PPT

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

    下载
      <?php  
      namespace AppExceptions;
    
      use Exception;
    
      class XxxException extends Exception
      {
    
      /**
      * @Message('短信验证码错误')
      */  
      const SMS_CODE_IS_ERROR = '300000000';
    
      /**
      * @Message('短信验证码类型错误')
      */  
      const SMS_CODE_TYPE_IS_ERROR = '300000001';
    
      /**
      * @Message('短信验证码不存在')
      */  
      const SMS_CODE_IS_NOT_EXISTS = '300000002';
      }
    
      ?>
    1. 伪代码

      //todo 验证码类型错误throw new XxxException(XxxException::SMS_CODE_IS_ERROR);

      程序现在是不是应该停下来了,因为当你exception的时候 下面代码不会执行了
      但是新的问题出现了,如果这样抛出异常,前端怎么办???????????
      此处小声bb 前端处理不了跟我什么关系啊,我是后台啊,你有问题找前端啊.
      那么我们假设一下 如果我们告诉前端的是

      {code:'300000000','message:'短信验证码错误'}

      是不是就很舒服了,前后端是一家 怎么能闹脾气呢
      那么如果 Code统一,请问出问题你在发愁什么? 是你的phpstorm不存在属性追踪吗?

    2. 怎么实现???????????????
       你问我,我也不到啊  我只能给你这个啊

        <?php
      
      namespace AppExceptions;use AppFactoryParseException; //解释异常的工厂 嫌弃名字长就没加Factory  use AppTraitsResponseTrait; //这个是我自己写的一个简单的trait 也会一并贴上去use IlluminateDatabaseEloquentModelNotFoundException;use IlluminateFoundationExceptionsHandler as ExceptionHandler;use IlluminateHttpJsonResponse;use IlluminateHttpResponse;use IlluminateSupportStr;use IlluminateValidationValidationException;use SymfonyComponentHttpKernelExceptionMethodNotAllowedHttpException;use SymfonyComponentHttpKernelExceptionNotFoundHttpException;use Throwable;class Handler extends ExceptionHandler{
        use ResponseTrait;
      
        /**
         * A list of the exception types that are not reported.
         *
         * @var array
         */
        protected $dontReport = [
            //
        ];
      
        /**
         * A list of the inputs that are never flashed for validation exceptions.
         *
         * @var array
         */
        protected $dontFlash = [
            'current_password',
            'password',
            'password_confirmation',
        ];
      
        /**
         * Register the exception handling callbacks for the application.
         *
         * @return void
         */
        public function register()
        {
            $this->reportable(function (Throwable $e) {
                //
            });
        }
      
        public function render($request, $e)
        {
            //数据库没查到数据或者数据是softdelete
            if ($e instanceof ModelNotFoundException) {
                return $this->error('500', '数据不存在或已删除');
            }
            //非允许请求方式
            if ($e instanceof MethodNotAllowedHttpException) {
                return $this->error('422', '请求方式错误');
            }
            //验证失败
            if ($e instanceof ValidationException) {
                return $this->error(412, current(current($e->errors())));
            }
            //这里是为了兼容其他的一些错误
            if (Str::length($e->getMessage()) > 1 && Str::length($e->getCode()) > 1) {
                return $this->error($e->getCode(), $e->getMessage());
            }
            //处理我们自己的错误 
            $result = ParseException::parseException($e);
            //这里判断的原因很简单 因为可能这个code没有按照规范声明 
            if (is_array($result)) {
                return $this->error($result['code'], $result['message']);
            }
            // Object Not Found  你懂我意思吧?
            if ($e instanceof NotFoundHttpException) {
                return $this->error('404', '页面路径不存在');
            }
            //这里可以根据自己是否需要做兜底而决定是否兜底
        }}

      parseException

      <?php
      
      namespace AppFactory;use IlluminateSupportFacadesLog;class ParseException{
        public static function parseException(Throwable $exception)
        {
        //注解 不懂得话建议直接看文档->反射 ,我讲不明白这个东西
            $annotation = new ReflectionClass($exception);
            //翻转 成code->constant
            $values = array_flip($annotation->getConstants());
            if (empty($values)) {
                return false;
            }
            //拿到对应的constant
            $constant = $values[$exception->getMessage()];
            //constant反射
            $annotation_text = new ReflectionClassConstant($exception, $constant);
            //获取属性注释内容
            $comment = $annotation_text->getDocComment();
      
            try {
            //正则大法好 建议留意此处 
                preg_match("/Message('(.*?)')(\r\n|\r|\n)/U", $comment, $result);
            } catch (Throwable $e) {
                return false;
            }
      
            if (false === isset($result[1])) {
                return false;
            }
            return [
                'code' => $exception->getMessage(),
                'message' => $result[1]
            ];
        }}

      不要问我要 ResponseTrait  我相信一个简单的 响应实现你是ok的
      这样实现的意义就是为了不管谁接手项目前端后端 看到错误信息一目了然,就算某天领导说不要需要告诉用户短信什么错了,就告诉他你短信错了,你只需要去改constant而已!
      并且可读性高,ide支持 ,如果你觉得不合适,那我没辙了 ,我尽力了

    3. 性能损耗
       目前没发现很明显的性能损耗,给出的调优方案也是 如果可以的话注解的类的属性列表(让你留意的地方)可以做缓存而已 ,(因为我目前不需要去考虑这个,laravels大法好)

  • 不出意外的话我的代码你拿着直接贴进去就可以用,但是我不建议你这么做,因为一次吃饱不代表能一直吃饱,我希望你能清楚起码也要点赞,不能白嫖这个道理

    我第一次写markdown  如果有什么写的不好的,可以及时留言我看到会尽力去改,如果有明显的代码错误,请提示我,我好把你的留言删除掉 .

    不要企图假装努力,因为结果不会陪你一起假装~! (这个字的颜色怎么改?)

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

WorkBuddy
WorkBuddy

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

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

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

26

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

46

2026.03.12

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

178

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

51

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

92

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

102

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

227

2026.03.05

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

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

532

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

171

2026.03.04

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
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号