ThinkPHP6项目基操(13.实战部分 项目中的自定义异常处理总结 错误页面API错误)
项目中的自定义异常处理总结 错误页面&API错误
- 前言
- 一、异常分类
- 1. 控制器找不到
- 2. 方法找不到
- 3. 请求资源不存在
- 4. 系统內部异常、HTTP异常等
- 二、异常处理
- 1. 前置处理
- 2. 异常处理详细代码
- (1) 控制器找不到
- (2) 方法找不到
- (3) 请求资源不存在及系统错误异常
- 三、异常检测
前言
一般项目中路由分为返回模板引擎页面
和返回api接口json数据
,两种方式异常需要返回不同的内容,如果是模板引擎页面遇到异常需要返回错误页面,如果是api接口遇到异常需要返回json数据。
开发模式和上线模式应该返回不同的内容,开发模式应该尽可能返回具体的错误信息,上线模式则不能返回具体的错误信息,一般显示“服务器错误,请稍后重试”类似友好的提示,而不是显示一堆报错代码(既不友好又不安全)。
如果有更好的方法,欢迎提出意见。
一、异常分类
1. 控制器找不到
在访问路由时,若控制器不对,需要使用空控制器
拦截报错。
2. 方法找不到
方法找不到可以修改app目录下的BaseController控制器重写__call方法。
3. 请求资源不存在
自定义拦截报错信息,可以使用Provider自定义错误处理类,重写render方法,根据不同的错误返回不同的数据。
4. 系统內部异常、HTTP异常等
同第3点。
二、异常处理
1. 前置处理
(1)
.env
文件定义APP_DEBUG
区分开发模式和线上模式,true表示开发模式,false表示线上模式:
APP_DEBUG = true
(2) 在
app/common.php
文件定义api
返回的数据格式:
function show($status, $message = 'error', $data = [], $httpStatus = 200){$result = ["status" => $status,"message" => $message,"result" => $data];return json($result, $httpStatus);
}
(3) 在当前应用下新建一个provider.php,并指定自定义异常处理类:
<?php// 容器Provider定义文件
return ['think\exception\Handle' => 'app\\admin\\exception\\Http',
];
(4) 定义状态码配置,可以在
config
文件夹下新建status.php
添加相应的状态码配置:
<?phpreturn ["success" => 1,"error" => 0,"http_status" => ["not_found" => 404,"validate_error" => 422,"internal_error" => 500]
];
(5) 准备错误页面(404,500等)
2. 异常处理详细代码
(1) 控制器找不到
在app/controller
目录新建Error
类(文件名固定为Error
):
这里需要注意的是,多应用的控制器应该定义在应用文件夹里,这里定义在app目录是为了作用于app下全部应用。
<?phpnamespace app\controller;class Error
{public function __call($name, $arguments){if(request()->isAjax()){return show(config("status.error"), env('app_debug') ? "控制器{$name}找不到" : '当前请求资源不存在,请稍后再试', [], config("status.http_status.not_found"));}else{return view(root_path() . 'public/error/admin/404.html', ['e' => env('app_debug') ? "控制器{$name}找不到" : '当前请求资源不存在,请稍后再试'], config("status.http_status.not_found"));}}
}
(2) 方法找不到
在app/BaseController.php
控制器添加 __call
方法:
public function __call($name, $arguments){if(request()->isAjax()){return show(config("status.error"), env('app_debug') ? "找不到{$name}方法" : '当前请求资源不存在,请稍后再试', [], config("status.http_status.not_found"));}else{return view(root_path() . 'public/error/admin/404.html', ['e' => env('app_debug') ? "{$name}方法找不到" : '当前请求资源不存在,请稍后再试'], config("status.http_status.not_found"));}}
(3) 请求资源不存在及系统错误异常
app\\admin\\exception\\Http
:
<?phpnamespace app\admin\exception;
use ErrorException;
use Exception;
use InvalidArgumentException;
use ParseError;
use PDOException;
use think\exception\ClassNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\RouteNotFoundException;
use think\Response;
use Throwable;
use TypeError;class Http extends Handle
{/*** Render an exception into an HTTP response.** @access public* @param \think\Request $request* @param Throwable $e* @return Response*/public function render($request, Throwable $e): Response{$returnCode = config("status.error");$returnMessage = "系统异常,请稍后再试";$returnData = [];$httpStatus = 500;if($e instanceof BusinessException){ // 自定义添加的业务异常$returnMessage = $e->getMessage();$httpStatus = config("status.http_status.business_error");}else if($e instanceof ValidateException){$returnMessage = $e->getError();$httpStatus = config("status.http_status.validate_error");}else if (($e instanceof ClassNotFoundException || $e instanceof RouteNotFoundException) || ($e instanceof HttpException && $e->getStatusCode() == 404)) {$returnMessage = env('app_debug') ? $e->getMessage() : '当前请求资源不存在,请稍后再试';$httpStatus = config("status.http_status.not_found");}else if ($e instanceof Exception || $e instanceof PDOException || $e instanceof InvalidArgumentException || $e instanceof ErrorException || $e instanceof ParseError || $e instanceof TypeError || ($e instanceof HttpException && $e->getStatusCode() == 500)) {$returnMessage = env('app_debug') ? $e->getMessage() : '系统异常,请稍后再试';$httpStatus = config("status.http_status.internal_error");}if(request()->isAjax()){return show($returnCode, $returnMessage, $returnData, $httpStatus);}else{if($httpStatus == config("status.http_status.not_found")){$errorUrl = 'public/error/admin/404.html';}else{$errorUrl = 'public/error/admin/error.html';}return view(root_path() . $errorUrl, ['e'=>$returnMessage], $httpStatus);}}
}
以上代码中返回的错误信息e
,需要在错误页面(404,error)显示:
<p class="error-message">{$e ?? ''}</p>
三、异常检测
异常检测分浏览器页面访问异常
和api接口返回异常
,还需要检查开发模式
和线上模式
。
- 控制器不存在
- 方法不存在
- 主动抛出异常
- 系统抛出异常
Tips:
api
接口可以使用Postman
工具模拟,添加Headers
:
Content-Type
为application/x-www-form-urlencoded
X-Requested-With
为xmlhttprequest
(博主比较懒就不贴截图了,但是都测试过,同志们自己试一下,算了还是贴一张吧)
⭐️重磅推荐:免费商用电商系统
ThinkPHP6项目基操(13.实战部分 项目中的自定义异常处理总结 错误页面API错误)相关推荐
- ThinkPHP6项目基操(15.实战部分 阿里云短信redis)
阿里云短信redis 一.安装阿里云短信SDK 二.封装到项目lib中 三.radis记录验证码 1. 安装redis服务 2. 可视化redis管理软件 3. PHP安装redis扩展 4. 配置缓 ...
- ThinkPHP6项目基操目录
前言 ThinkPHP是一个免费开源的,快速.简单的面向对象的轻量级PHP开发框架,是为了敏捷WEB应用开发和简化企业应用开发而诞生的.ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色 ...
- ThinkPHP6项目基操(11.实战部分 部署后台静态页面模板及后台登录页面)
实战部分 部署后台静态页面模板及后台登录页面 前言 一.部署静态资源到项目 1.新建后台静态资源文件夹 二.后台登录页面 1. 目录结构 2. 模板字符串替换配置 前言 网站后台一般是在基础静态页面上 ...
- ThinkPHP6项目基操(4.拦截无效请求 控制器或方法不存在)
拦截无效请求 控制器或方法不存在 一.默认无效请求 二.显示具体错误信息 方法1.配置`config/app.php` 方法2. 配置`.env`环境变量 三.处理错误 1. 方法不存在 2. 控制器 ...
- php登陆项目,ThinkPHP6项目基操(14.实战部分 中间件处理登录流程)
一.定义中间件 namespace app\middleware; class Check { public function handle($request, \Closure $next) { i ...
- ThinkPHP6项目基操(20.实战部分 数据库操作返回值总结)
数据库操作返回值总结 0. 前言 1. Db类操作数据库 1.1 新增 1.2 更新 1.3 删除 1.3.1 单条删除 1.3.2 批量删除 1.4 查询 1.4.1 单笔记录 1.4.2 多笔记录 ...
- ThinkPHP6项目基操(19.实战部分 Mysql模型事务操作)
模型事务操作 前言 1. Mysql数据库注意 2. thinkPHP模型使用事务 前言 事务操作在复杂的数据库操作的时候尤为重要,特别是在操作多张表的时候,如果某一步骤出错了,就会导致有脏数据,会很 ...
- ThinkPHP6项目基操(18.实战部分 表单令牌Token 防CSRF)
表单令牌Token 0. 前言 1. TP6 令牌token使用 1.1 表单提交 1.2 AJAX提交 2. TP6 令牌token验证 2.1 路由验证 2.2 控制器验证 2.3 验证器验证 0 ...
- ThinkPHP6项目基操(17.实战部分 Filesystem文件上传)
Filesystem文件上传 控制器: <?php namespace app\admin\controller; use app\BaseController; use think\facad ...
最新文章
- 02移动端布局基础之流式布局项目实战(京东移动端首页)
- 启用CentOS6.5 64位安装时自带的MySQL数据库服务器
- Android 编译环境的依赖库安装
- Django从理论到实战(part28)--ORM常用Field详解
- ora-01092: oracle 实例终止.强制断开连接,undo表空间故障特殊恢复(二)------ORA-01092: ORACLE 实例终止。强制断开连接...
- 斗鱼回应与虎牙合并;Android 11 Beta 3 发布| 极客头条
- 用curl访问HTTPS站点并登录
- MapReduce on Yarn 的流程和架构图
- R语言︱非结构化数据处理神器——rlist包
- 论文写作——算法部分写作心得
- 新MacBook Pro软件安装记录
- 戴尔笔记本电脑插入有线耳机后仍然外放的一种解决办法
- LeetCode1436 旅行终点站
- 参考线平滑-FemPosDeviation-SQP
- 无人驾驶学习(二):定位与导航
- 领淘宝优惠券的微信小程序
- 微信服务器与客户端消息通讯机制,微信在部分地区发生连接故障,你遇到了么?...
- Android studio连接(逍遥)模拟器
- paypal是怎么收费的?
- 什么是RC低通滤波电路
热门文章
- ajax核心技术1---XMLHttpRequset对象的使用
- 我会铭记这一天:2016年10月25日
- DB2常用函数:字符串函数
- 在安全模式下激活xp
- 【转】vc6.0移植到VS2010遇到的问题,散分给大家,虽然分不多,各位帮忙
- SSIS 错误代码 DTS_E_OLEDB_EXCEL_NOT_SUPPORTED 没有可用的 OLE DB 访问接口 SSIS 的 64 位版本中不支持 Excel 连接管理器...
- 但救地球要紧的飞鸽传书
- 免费软件做的不错的,这里要说一个叫《飞秋》的软件
- 便把他手中的i698源代码拐杖转了一圈
- 《飞秋下载》介绍过的求伯君,看看!