0

0

实例讲解PHP如何在Yii框架中进行错误和异常处理

醉折花枝作酒筹

醉折花枝作酒筹

发布时间:2021-07-16 09:11:54

|

2834人浏览过

|

来源于CSDN

转载

yii已经默认已经在capplication上实现了异常和错误的接管,这是通过php的set_exception_handler,set_error_handler实现的。通过这两个php内置函数,可以对程序中未捕获的异常以及错误进行接管处理,从而提高程序的可维护性。

实例讲解PHP如何在Yii框架中进行错误和异常处理

默认情况下,Yii会将异常处理分配给CApplication::handleException, 将错误处理分配给CApplication::handleError,但是可以通过在入口文件中定义YII_ENABLE_EXCEPTION_HANDLER, YII_ENABLE_ERROR_HANDLER两个常量为false禁止使用Yii的异常和错误接管机制。

以下内容中,将异常和错误统称为错误,如有必要会进行详细区分说明。YII_DEBUG常量(默认为false, 可以在入口文件中设置)对错误信息的显示有很重要的影响,debug模式下,错误的输出是最详细的。而程序一旦投入运行,则应将YII_DEBUG修改为false。

无论是否处于debug模式,Yii程序产生错误时均会将相关错误信息进行记录(错误级别为error, 分类默认为application)。不同之处是debug模式时会直接在web页上显示详细信息。

立即学习PHP免费学习笔记(深入)”;

CApplication:: handleError($code,$message,$file,$line)

上面的方法实现了相关逻。特别注意restore_error_handler,restore_exception_handler两个函数,如果没有这两个函数的调用,那么在后续的错误处理过程中,当再次产生异常或是错误时,又会调用CApplication:: handleError ,从而可能造成死循环,故Yii在此处临时禁止了使用CApplication:: handleError 接管后续的错误和异常(使用php默认的错误处理机制),这就保证了不会因之产生循环调用。

PHP错误的处理当产生错误时,PHP会在日志中记录哪些信息?错误代码(即PHP的E_ERROR E_WARNING  E_STRICT E_DEPRECATED)消息内容(如 Undefined vaiable $input)产生错误的文件路径产生错误的行号额外的跟踪回溯信息(这是通过debug_backtrace实现的)当前URL

除了记录相应日志之外,Yii还会对错误进行后续处理(如中断运行、显示错误页等),默认情况下错误的处理会交给CErrorHandler组件处理(但可以通过给CApplicaton绑定onError事件处理器而实现错误处理的二次接管,此处的设计很灵活!)。

此时将产生一个CErrorEvent(并包含$code,$message,$file,$line几项关键参数),传递给CErrorHandler组件进行处理。具体是交给CErrorHandler::handleError处理之。这个流程主要是将错误相关信息进行整理,并以合适的方式进行显示。

是否为debug模式(YII_DEBUG==true),对错误信息的显示结果有极大影响。调试模式下我们希望能显示详细的错误跟踪信息,而在生产模式下,我们希望给用户显示友好的页面。所以,此处的错误显示有所不同,下面区分说明之。

当处于调试模式时,将直接渲染exception视图展示错误。将按以下路径搜索:

protected/views/system/exception.php

YII_PATH/views/exception.php

显然,默认情况下并没有在应用程序中定义views/system目录,故会使用系统框架自带的视图文件。最终包含的文件将是Yii框架中的views/exception.php。

从以上分析中可以得知,在调试模式下如果我们要使用自定义异常页面(一般这么做的意义可能不大),则需要配置文件protected/views/system/exception.php, 可使用的变量即$data。

当处于非调试模式下时,会作如下处理:

配置文件中若为errorHandler组件定义了errorAction路由信息,则直接运行之,否则执行第2步流程。

尝试加载error视图,按以下路径搜索(第一个搜索到的文件将被使用)

protected/views/system/zh_cn/error500.php

protected/views/system/error500.php

protected/views/system/zh_cn/error.php

protected/views/system/error.php

YII_PATH/views/zh_cn/error500.php

YII_PATH/views/error500.php

YII_PATH/views/zh_cn/error.php

Y II_PATH/views/error.php

异常的处理根据前面的分析,异常的处理机制与错误处理机制类似,也会记录日志,级别是error, 分类为"exception.$EXCEPTIONCLASS", 若是CHttpException类异常,分类名称则为exception.CHttpException.$STATUS_CODE。如数据的异常分类称为exception.CDbException。

接下来将错误事件CExceptionEvent交由errorHandler处理,所有错误信息都由CExceptionEvent对象传递而来。处理方法如下:

如果是调试模式,则按以下顺序搜索视图文件,第一个搜索到的文件将被使用

protected/views/system/exception.php

YII_PATH/views/exception.php

如果是非调试模式,并在配置文件中为errorHandler组件定义了errorAction属性路由,则运行之,否则进入第3步。

按以下顺序尝试加载视图文件,第一个搜索到的文件将被使用

protected/views/system/zh_cn/error500.phpprotected/views/system/error500.phpprotected/views/system/zh_cn/error.phpprotected/views/system/error.phpYII_PATH/views/zh_cn/error500.phpYII_PATH/views/error500.phpYII_PATH/views/zh_cn/error.phpY II_PATH/views/error.php

使用流程图描述,会更清楚一些:搜寻视图文件流程比较重要,因为它关系到我们如何自定义错误页面的细节问题,后续的流程图详细描述其过程。

f741eb7599c3a33ffc60c642f4eb8650.png

从图中可以看出,最容易的方式还是给errorHandler组件设置errorAction属性指定错误发生的路由

e50507ce5d72c720d03501cbb722d5b9.png

晓象AI资讯阅读神器
晓象AI资讯阅读神器

晓象-AI时代的资讯阅读神器

下载

一般而言,我们最关心的是生产模式下错误页面的显示问题,经过以上分析,有两种方法可用:

配置文件中为errorHandler组件定义errorAction路由属性(应该优先使用这个方式,以达到灵活配置目的)

定义以下文件中的任意一个,实现自定义错误页(不推荐)

Protected/views/system/zh_cn/error500.php

protected/views/system/error500.php

protected/views/system/zh_cn/error.php

protected/views/system/error.php

第1种方式灵活可控,可以在控制器中指定视图文件,灵活可控。

使用错误处理器示例

yii\web\ErrorHandler 注册成一个名称为errorHandler应用组件, 可以在应用配置中配置它类似如下:

return [
'components' => [
'errorHandler' => [
'maxSourceLines' => 20,
],
],
];

使用如上代码,异常页面最多显示20条源代码。

如前所述,错误处理器将所有非致命PHP错误转换成可获取异常,也就是说可以使用如下代码处理PHP错误:

use Yii;
use yii\base\ErrorException;
try {
10/0;
} catch (ErrorException $e) {
Yii::warning("pision by zero.");
}
// execution continues...

如果你想显示一个错误页面告诉用户请求是无效的或无法处理的,可简单地抛出一个 yii\web\HttpException异常, 如 yii\web\NotFoundHttpException。错误处理器会正确地设置响应的HTTP状态码并使用合适的错误视图页面来显示错误信息。

use yii\web\NotFoundHttpException;
throw new NotFoundHttpException();

自定义错误显示

yii\web\ErrorHandler错误处理器根据常量YII_DEBUG的值来调整错误显示, 当YII_DEBUG 为 true (表示在调试模式),错误处理器会显示异常以及详细的函数调用栈和源代码行数来帮助调试, 当YII_DEBUG 为 false,只有错误信息会被显示以防止应用的敏感信息泄漏。

补充: 如果异常是继承 yii\base\UserException,不管YII_DEBUG为何值,函数调用栈信息都不会显示, 这是因为这种错误会被认为是用户产生的错误,开发人员不需要去修正。

yii\web\ErrorHandler 错误处理器默认使用两个视图显示错误:

@yii/views/errorHandler/error.php: 显示不包含函数调用栈信息的错误信息是使用, 当YII_DEBUG 为 false时,所有错误都使用该视图。

@yii/views/errorHandler/exception.php: 显示包含函数调用栈信息的错误信息时使用。

可以配置错误处理器的 yii\web\ErrorHandler::errorView 和 yii\web\ErrorHandler::exceptionView 属性 使用自定义的错误显示视图。

使用错误操作

使用指定的错误操作 来自定义错误显示更方便, 为此,首先配置errorHandler组件的 yii\web\ErrorHandler::errorAction 属性,类似如下:

return [
'components' => [
'errorHandler' => [
'errorAction' => 'site/error',
],
]
];

yii\web\ErrorHandler::errorAction 属性使用路由到一个操作, 上述配置表示不用显示函数调用栈信息的错误会通过执行site/error操作来显示。

可以创建site/error 操作如下所示:

namespace app\controllers;
use Yii;
use yii\web\Controller;
class SiteController extends Controller
{
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
];
}
}

上述代码定义error 操作使用yii\web\ErrorAction 类,该类渲染名为error视图来显示错误。

除了使用yii\web\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 状态码,错误码,错误调用栈等。

补充: 如果你使用 基础应用模板 或 高级应用模板, 错误操作和错误视图已经定义好了。

自定义错误格式

错误处理器根据响应设置的格式来显示错误, 如果yii\web\Response::format 响应格式为html, 会使用错误或异常视图来显示错误信息,如上一小节所述。 对于其他的响应格式,错误处理器会错误信息作为数组赋值给yii\web\Response::data属性,然后转换到对应的格式, 例如,如果响应格式为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; charset=UTF-8
{
"name": "Not Found Exception",
"message": "The requested resource was not found.",
"code": 0,
"status": 404
}

可在应用配置中响应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;
}
},
],
],
];

上述代码会重新格式化错误响应,类似如下:

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; charset=UTF-8
{
"success": false,
"data": {
"name": "Not Found Exception",
"message": "The requested resource was not found.",
"code": 0,
"status": 404
}
}

推荐学习:php视频教程

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2687

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1662

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1522

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

953

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1420

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1235

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1488

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1306

2023.11.13

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.9万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 8.3万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号