Yii 2 错误处理完全指南ErrorHandler 组件、异常页面定制与多格式错误响应【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址: https://gitcode.com/gh_mirrors/yi/yii2本篇技术指南以 Yii 2 内置的yii\web\ErrorHandler错误处理器为核心系统讲解它在 Web 应用请求生命周期参见 runtime-overview.md中如何接管 PHP 错误与异常从“非致命错误转异常”的底层机制、YII_DEBUG与YII_ENABLE_ERROR_HANDLER常量的行为差异到使用errorAction自定义错误页面、以及按response组件格式输出 HTML / JSON / RAW 错误响应的完整方案。读完本文你将掌握在 Yii 2 应用里统一、安全、可定制地处理错误与异常的全部关键技术。错误处理器能为你做什么Yii 内置的yii\web\ErrorHandler错误处理器把 PHP 原本“粗糙”的错误处理变成了一种愉悦的体验。它主要做了四件事把全部非致命 PHP 错误如 warning、notice转换为可捕获的异常从而让try...catch可以统一拦截它们在调试模式YII_DEBUG true下异常与致命错误会以详细的调用栈call stack和源码行的形式展示支持使用**专用的控制器动作controller action**来展示错误即errorAction机制支持多种错误响应格式HTML、JSON、RAW 等。从源码看yii\web\ErrorHandler继承自抽象基类yii\base\ErrorHandlerframework/base/ErrorHandler.phpWeb 端渲染逻辑实现在 framework/web/ErrorHandler.php 中控制台应用则使用yii\console\ErrorHandlerframework/console/ErrorHandler.php以纯文本方式渲染异常。启用与禁用错误处理器默认是启用的。如果你确实想关闭它可以在应用的入口脚本如web/index.php中把常量YII_ENABLE_ERROR_HANDLER定义为falsedefined(YII_ENABLE_ERROR_HANDLER) or define(YII_ENABLE_ERROR_HANDLER, false);框架在 framework/BaseYii.php 中兜底定义了该常量默认值为truedefined(YII_ENABLE_ERROR_HANDLER) or define(YII_ENABLE_ERROR_HANDLER, true);当该常量保持默认时应用启动流程会调用 framework/base/Application.php 中的registerErrorHandler()把配置好的errorHandler组件实例注册为 PHP 的异常处理器、错误处理器与关闭函数处理器register()方法见 framework/base/ErrorHandler.php。注意关闭该功能会导致 PHP 错误与异常失去统一出口生产环境通常不应这样做。使用错误处理器yii\web\ErrorHandler以应用组件参见 structure-application-components.md的形式注册组件名为errorHandler可通过Yii::$app-errorHandler访问。你可以在应用配置中像下面这样配置它return [ components [ errorHandler [ maxSourceLines 20, ], ], ];上述配置会让异常页面最多展示 20 行源码。需要指出的是源码中 framework/web/ErrorHandler.php 给出的默认值是 19 行$maxSourceLines 19另外还有一个maxTraceSourceLines 13用于控制调用栈中每一帧源码行的展示数量。下面是 Web 版错误处理器常用的可配置属性速查表属性默认值作用maxSourceLines19异常页面主错误位置展示的源码行数上限maxTraceSourceLines13调用栈中每个栈帧展示的源码行数上限errorActionnull无调用栈信息时执行的路由如site/errornull表示由错误处理器自行渲染errorViewyii/views/errorHandler/error.php无调用栈信息时使用的视图exceptionViewyii/views/errorHandler/exception.php含调用栈信息时使用的视图callStackItemViewyii/views/errorHandler/callStackItem.php渲染单个调用栈帧的视图previousExceptionViewyii/views/errorHandler/previousException.php渲染前置异常链的视图displayVars[_GET, _POST, _FILES, _COOKIE, _SESSION]调试页面上展示的 PHP 全局变量列表traceLine{html}调用栈文件行的 HTML 模板此外基类yii\base\ErrorHandler还提供两个值得了解的安全相关属性discardExistingOutput默认true展示错误前丢弃已输出的页面内容避免错误页面混入脏数据memoryReserveSize默认262144即 256KB预分配内存用于在内存耗尽out of memory时仍能渲染错误见 framework/base/ErrorHandler.php。非致命错误也是可捕获的异常正如前文所说错误处理器会把所有非致命 PHP 错误转换为可捕获的异常。这背后的实现是yii\base\ErrorHandler::handleError()framework/base/ErrorHandler.php当错误级别命中当前error_reporting()掩码时它构造一个yii\base\ErrorException并直接throw出去。因此你完全可以用下面的代码来“接住” PHP 错误use Yii; use yii\base\ErrorException; try { 10/0; } catch (ErrorException $e) { Yii::warning(Division by zero.); } // 程序继续执行...需要留意的边界在 PHP 7.4 之前__toString()内不允许抛出异常handleError()对__toString上下文做了特殊处理直接走handleException()并退出同时错误处理器会“手动”加载ErrorException类因为错误可能发生在自动加载本身失效的时刻。这些细节见 framework/base/ErrorHandler.php。抛出 HTTP 异常以呈现规范错误页如果你希望向用户展示“请求无效或异常”的错误页面直接抛出一个yii\web\HttpException即可例如yii\web\NotFoundHttpException。错误处理器会自动设置响应的 HTTP 状态码并使用合适的错误视图展示错误信息use yii\web\NotFoundHttpException; throw new NotFoundHttpException();yii\web\HttpExceptionframework/web/HttpException.php通过$statusCode属性携带标准 HTTP 状态码如 403、404、500并利用Response::$httpStatuses生成用户友好的异常名如 Not Found Exception。实践中常带状态码与消息if ($item null) { // item 不存在 throw new \yii\web\HttpException(404, The requested Item could not be found.); }错误记录日志行为每次异常被处理时基类还会调用logException()framework/base/ErrorHandler.php把异常写入日志普通异常按类名分类HttpException按yii\web\HttpException:{statusCode}分类ErrorException按类名:严重级别分类。这意味着你可以在日志中按状态码检索 404/500 等错误。自定义错误显示错误处理器会根据常量YII_DEBUG的值调整错误展示方式YII_DEBUG true调试模式展示带有详细调用栈和源码行的异常页面便于定位问题YII_DEBUG false只展示错误消息本身避免泄露应用敏感信息如文件路径、SQL 等。Info: 如果异常是yii\base\UserException的子类则无论YII_DEBUG取值如何都不会展示调用栈。因为这类异常被认为是由用户误操作引起的开发者无需修复任何东西。yii\web\HttpException正是UserException的子类所以 404 页面通常不会暴露调用栈。默认情况下错误处理器使用两个内置视图展示错误yii/views/errorHandler/error.php源码见 framework/views/errorHandler/error.php在不展示调用栈时使用。当YII_DEBUG false时这是唯一会展示的错误视图——一个简洁的白底页面仅包含错误名、消息、时间戳等并输出“An internal server error occurred.”之类的通用文案。yii/views/errorHandler/exception.php源码见 framework/views/errorHandler/exception.php在展示调用栈时使用。这是调试模式下的“豪华”页面包含异常类型链接、_GET/_POST/_SESSION等请求全局变量由displayVars控制、每个栈帧的可折叠源码块、复制栈信息按钮等。判断逻辑位于 framework/web/ErrorHandler.php当响应格式为 HTML 且!YII_DEBUG或异常为UserException时走errorView否则走exceptionView。你可以通过配置errorView与exceptionView属性换成自己的视图从而自定义错误展示。不过更推荐的做法是使用下面的errorAction机制。使用错误动作Error Actions自定义错误展示的更好方式是使用专用的错误动作action。首先在配置中把errorHandler组件的errorAction属性指向一个路由return [ components [ errorHandler [ errorAction site/error, ], ] ];errorAction接收一个动作路由。上面的配置表明当错误需要在不展示调用栈的情况下展示时执行site/error动作。从源码看framework/web/ErrorHandler.php此时错误处理器会清空视图、调用Yii::$app-runAction($this-errorAction)并把动作返回值作为响应数据。然后创建SiteController中的error动作namespace app\controllers; use Yii; use yii\web\Controller; class SiteController extends Controller { public function actions() { return [ error [ class yii\web\ErrorAction, ], ]; } }上面的代码使用yii\web\ErrorAction类framework/web/ErrorAction.php定义error动作它会渲染一个名为error的视图views/site/error.php。ErrorAction的关键行为包括init()中通过findException()从Yii::$app-errorHandler-exception获取当前异常如果错误动作被直接访问而没有异常上下文则自动抛出NotFoundHttpException(Page not found.)见 framework/web/ErrorAction.php避免误访问时出现空白页运行时会用setStatusCodeByException()同步响应状态码对 AJAX 请求直接返回错误名: 错误消息的纯文本对普通请求渲染 HTML 视图见 framework/web/ErrorAction.php对UserException用户输入类错误展示真实消息对其他异常则展示defaultMessage默认 An internal server error occurred.防止泄露内部细节见 framework/web/ErrorAction.php。除了使用ErrorAction类你也可以用普通动作方法定义error动作public function actionError() { $exception Yii::$app-errorHandler-exception; if ($exception ! null) { return $this-render(error, [exception $exception]); } }无论采用哪种方式都需要创建视图文件views/site/error.php。如果错误动作定义为yii\web\ErrorAction在该视图文件中你可以使用以下变量name错误名称message错误消息exception异常对象通过它可以获取更多有用信息例如 HTTP 状态码、错误码、错误调用栈等。Info: 如果使用基础项目模板或高级项目模板错误动作和错误视图通常已经定义好了基础模板的SiteController::actions()中就包含error动作视图为views/site/error.php。Note: 如果需要在错误处理器中进行重定向请采用下面的方式Yii::$app-getResponse()-redirect($url)-send(); return;在发送响应后立即return避免后续渲染继续执行。若动作方法返回了Response对象ErrorHandler也会直接把它作为响应结果见 framework/web/ErrorHandler.php。一个可直接落地的错误视图示例下面是views/site/error.php的典型实现同时兼容ErrorAction传入的name/message/exception变量?php /** var string $name 错误名称 */ /** var string $message 错误消息 */ /** var \Throwable $exception 异常对象 */ use yii\helpers\Html; $this-title $name; ? div classsite-error h1? Html::encode($name) ?/h1 div classalert alert-danger ? nl2br(Html::encode($message)) ? /div p 上述错误发生在 Web 服务器处理你的请求时。 如果你认为这是服务器错误请联系我们谢谢。 /p /div自定义错误响应格式错误处理器会根据 response 组件的格式设置来展示错误。如果yii\web\Response::format是html则使用前面提到的 error / exception 视图对于其他格式错误处理器会把异常的数组表示赋值给yii\web\Response::data属性再由响应组件按对应格式转换输出。数组表示由convertExceptionToArray()生成framework/web/ErrorHandler.php包含的字段随模式不同而增减基础字段name异常名、message异常消息、code错误码当异常为HttpException时追加statusHTTP 状态码YII_DEBUG true时追加type异常类名、file、line、stack-trace若为yii\db\Exception还追加error-infoUserException例外不输出栈信息存在前置异常时递归追加previous字段非调试模式下非UserException/HttpException的异常会被替换为通用的 500HttpException消息 An internal server error occurred.防止泄露内部细节。例如当响应格式为json时你会看到类似下面的响应HTTP/1.1 404 Not Found Date: Sun, 02 Mar 2014 05:31:43 GMT Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y Transfer-Encoding: chunked Content-Type: application/json; charsetUTF-8 { name: Not Found Exception, message: The requested resource was not found., code: 0, status: 404 }在 RESTful API 场景下前端通常期望统一包裹的错误结构。你可以通过响应response组件的beforeSend事件来定制错误响应格式在应用配置中注册事件处理器return [ // ... components [ response [ class yii\web\Response, on beforeSend function ($event) { $response $event-sender; if ($response-data ! null) { $response-data [ success $response-isSuccessful, data $response-data, ]; $response-statusCode 200; } }, ], ], ];上面的代码会把错误响应重排成如下格式注意这里把状态码强制改成了 200是否采纳取决于你的 API 约定——通常更推荐保留真实状态码并增加success标记HTTP/1.1 200 OK Date: Sun, 02 Mar 2014 05:31:43 GMT Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y Transfer-Encoding: chunked Content-Type: application/json; charsetUTF-8 { success: false, data: { name: Not Found Exception, message: The requested resource was not found., code: 0, status: 404 } }对于FORMAT_RAW格式错误处理器会直接把异常转换为字符串convertExceptionToString()非调试模式下统一返回 An internal server error occurred.适合纯文本接口。错误处理的内部流程速览综合以上源码一次典型的错误处理流程如下PHP 抛出错误或异常被yii\base\ErrorHandler::register()注册的处理器捕获set_exception_handler/set_error_handler/register_shutdown_function见 framework/base/ErrorHandler.phphandleException()记录当前异常、注销自身以避免递归、预置 500 状态码、写入日志并清空已输出内容见 framework/base/ErrorHandler.phpyii\web\ErrorHandler::renderException()根据响应格式与YII_DEBUG决定出口HTML 且配置了errorAction则运行动作HTML 无动作则渲染errorView或exceptionViewRAW 输出字符串其余格式输出数组见 framework/web/ErrorHandler.php响应组件最终把data按format序列化并发送给客户端致命错误fatal error由handleFatalError()在 shutdown 阶段兜底处理其渲染逻辑与普通异常一致见 framework/base/ErrorHandler.php。值得一提的是yii\console\ErrorHandlerframework/console/ErrorHandler.php对控制台应用如迁移、定时任务做了适配以纯文本输出异常类名、消息与栈帧并递归渲染前置异常便于在终端中阅读。常见问题与最佳实践生产环境务必YII_DEBUG false否则异常页会输出文件路径、源码与请求变量这是敏感信息泄露的主要来源之一。用户输入相关的校验失败用UserException子类既能展示给用户又不会泄露调用栈。业务层统一抛HttpException让错误处理器帮你设置状态码与响应格式而不是在控制器里手写http_response_code()。REST API 统一错误结构通过response组件的beforeSend事件包裹success/data字段或保留状态码 增加success标记让前端错误处理逻辑统一。错误日志联动logException()会自动按HttpException:{statusCode}分类记录配合 runtime-logging.md 中的日志配置可实现对 4xx/5xx 错误的监控与告警。延伸阅读运行时总览一次请求的完整生命周期响应组件与格式设置控制器与动作action、route视图的创建与渲染应用组件配置日志与监控核心实现源码framework/web/ErrorHandler.php、framework/base/ErrorHandler.php、framework/web/ErrorAction.php、framework/views/errorHandler/error.php【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址: https://gitcode.com/gh_mirrors/yi/yii2创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
前端实战:滚动监听实现顶部 logo 平滑显隐效果 开发弹窗、侧边抽屉、全屏遮罩这类组件时,经常会遇到一个问题:弹窗弹出后,底层页面依然可以滚动,体验很差。常见方案就是控制 body 的滚动,本文使用 jQuery 实现禁止页面滑动和恢复页面滑动,同时说明坑点。… · 2026/9/24 17:02:56
Visdom 窗口系统完全指南:Window ID、拖拽布局、程序化操作与实时参数编辑 Visdom 窗口系统完全指南:Window ID、拖拽布局、程序化操作与实时参数编辑 【免费下载链接】visdom Tool for real-time visualization, monitoring and collaborative analysis of AI/ML experiments and live data. Supports Python, PyTorch/Torch, NumPy, Tenso… · 2026/9/24 17:02:56
云手机哪个好用?系统兼容性、保活、网络维度分析,怎么选 云手机本质是部署在云端服务器上的 Android 虚拟设备,可实现本地设备关机后云端应用持续运行。本文从技术指标出发,整理了云手机的核心评估维度,对比市面主流几款产品的特性、优缺点,面向个人开发者、测试人员、应用托管用户提供选… · 2026/9/24 17:02:50
Linux man 手册与基本命令详解 1. 引言对于刚接触 Linux 的开发者来说,man 手册和基本命令是必须掌握的两项基础技能。man 手册是系统内置的权威参考文档,而基本命令则是日常操作系统的核心工具。本文将从 man 手册的使用方法讲起,再系统梳理常用 Linux 基本命令࿰… · 2026/9/24 17:36:27
连接器工程化选型策略 工程化选型不能只关注器件本身,而必须同时覆盖应用场景、制造工艺与供应链管理这三个关键维度。 连接器工程化选型流程摘要:连接器选型看似是一个元件选择问题,实际上是系统设计问题。如果工程师只根据针数、间距和额定电流进行选择&#… · 2026/9/24 17:36:27
苹果远程控制软件哪个好用 苹果远程控制软件推荐 苹果远程控制软件大多适配性差、体验参差不齐,很多果粉尝试过多款工具,都难以实现流畅稳定的跨设备远控。苹果远程控制软件想要适配iPhone、iPad、Mac全系列设备,不妨试试无界趣连2.0,它兼顾实用性与稳定性,完美解决苹… · 2026/9/24 17:36:02
09-基于STM32的独居老人智能监护系统设计 单片机型号(STM32)目录一、摘要二、设计要求三、原理图四、说明书预览五、QA作者简介:电类领域优质创作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导&#… · 2026/9/24 17:36:02
cat ,more,less,head,tail文件查看类命令 cat:查看文件内容在1.txt里面写一些东西cat -n 1.txt :内容前面带上行号more :文件内容太多时用这个命令,如果显示不全可以按空格来查看看完就自动退出less:于more一致 查看完按Q退出head;查看文件前十行tailÿ… · 2026/9/24 17:36:02
MongoDB mongodump mongorestore备份恢复实操记录 部署主机:10.10.10.128操作系统:CentOS Linux7.9.2009MongoDB版本:4.2.25部署日期:2026‑09‑20一、概述mongodump/mongorestore是MongoDB逻辑备份工具;导出BSON二进制文件,支持全实例、单库、单集合备份&a… · 2026/9/24 17:36:02
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44