搜尋
首頁php教程php手册实例讲解如何在PHP的Yii框架中进行错误和异常处理

Yii已经默认已经在CApplication上实现了异常和错误的接管,这是通过php的set_exception_handler,set_error_handler实现的。通过这两个PHP内置函数,可以对程序中未捕获的异常以及错误进行接管处理,从而提高程序的可维护性。这在大型系统是至关重要的,当发

Yii已经默认已经在CApplication上实现了异常和错误的接管,这是通过php的set_exception_handler,set_error_handler实现的。通过这两个PHP内置函数,可以对程序中未捕获的异常以及错误进行接管处理,从而提高程序的可维护性。这在大型系统是至关重要的,当发生错误时,我们希望能将相关详细信息记录,甚至是即时发送报警,从而缩短故障修复时间,提高整个系统的稳定性。
默认情况下,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页上显示详细信息。

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

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

2016317155836430.jpg (825×596)

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

2016317155904155.jpg (804×339)

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

配置文件中为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("Division 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
  }
}

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python中的SVM实例Python中的SVM实例Jun 11, 2023 pm 08:42 PM

Python中的支持向量机(SupportVectorMachine,SVM)是一个强大的有监督学习算法,可以用来解决分类和回归问题。SVM在处理高维度数据和非线性问题的时候表现出色,被广泛地应用于数据挖掘、图像分类、文本分类、生物信息学等领域。在本文中,我们将介绍在Python中使用SVM进行分类的实例。我们将使用scikit-learn库中的SVM模

VUE3入门实例:制作一个简单的视频播放器VUE3入门实例:制作一个简单的视频播放器Jun 15, 2023 pm 09:42 PM

随着新一代前端框架的不断涌现,VUE3作为一个快速、灵活、易上手的前端框架备受热爱。接下来,我们就来一起学习VUE3的基础知识,制作一个简单的视频播放器。一、安装VUE3首先,我们需要在本地安装VUE3。打开命令行工具,执行以下命令:npminstallvue@next接着,新建一个HTML文件,引入VUE3:<!doctypehtml>

学习Golang指针转换的最佳实践示例学习Golang指针转换的最佳实践示例Feb 24, 2024 pm 03:51 PM

Golang是一门功能强大且高效的编程语言,可以用于开发各种应用程序和服务。在Golang中,指针是一种非常重要的概念,它可以帮助我们更灵活和高效地操作数据。指针转换是指在不同类型之间进行指针操作的过程,本文将通过具体的实例来学习Golang中指针转换的最佳实践。1.基本概念在Golang中,每个变量都有一个地址,地址就是变量在内存中的位置。

Python中的VAE算法实例Python中的VAE算法实例Jun 11, 2023 pm 07:58 PM

VAE是一种生成模型,全称是VariationalAutoencoder,中文译作变分自编码器。它是一种无监督的学习算法,可以用来生成新的数据,比如图像、音频、文本等。与普通的自编码器相比,VAE更加灵活和强大,能够生成更加复杂和真实的数据。Python是目前使用最广泛的编程语言之一,也是深度学习的主要工具之一。在Python中,有许多优秀的机器学习和深度

Gin框架中的验证码使用实例Gin框架中的验证码使用实例Jun 23, 2023 am 08:10 AM

随着互联网的普及,验证码已经成为了登录、注册、找回密码等操作的必要流程。在Gin框架中,实现验证码功能也变得异常简单。本文将介绍如何在Gin框架中使用第三方库实现验证码功能,并提供示例代码供读者参考。一、安装依赖库在使用验证码之前,我们需要安装一个第三方库goCaptcha。安装goCaptcha可以使用goget命令:$goget-ugithub

PHP 简单网络爬虫开发实例PHP 简单网络爬虫开发实例Jun 13, 2023 pm 06:54 PM

随着互联网的迅速发展,数据已成为了当今信息时代最为重要的资源之一。而网络爬虫作为一种自动化获取和处理网络数据的技术,正越来越受到人们的关注和应用。本文将介绍如何使用PHP开发一个简单的网络爬虫,并实现自动化获取网络数据的功能。一、网络爬虫概述网络爬虫是一种自动化获取和处理网络资源的技术,其主要工作过程是模拟浏览器行为,自动访问指定的URL地址并提取所

Python中的GAN算法实例Python中的GAN算法实例Jun 10, 2023 am 09:53 AM

生成对抗网络(GAN,GenerativeAdversarialNetworks)是一种深度学习算法,它通过两个神经网络互相竞争的方式来生成新的数据。GAN被广泛用于图像、音频、文字等领域的生成任务。在本文中,我们将使用Python编写一个GAN算法实例,用于生成手写数字图像。数据集准备我们将使用MNIST数据集作为我们的训练数据集。MNIST数据集包含

快速上手Django框架:详细教程和实例快速上手Django框架:详细教程和实例Sep 28, 2023 pm 03:05 PM

快速上手Django框架:详细教程和实例引言:Django是一款高效灵活的PythonWeb开发框架,由MTV(Model-Template-View)架构驱动。它拥有简单明了的语法和强大的功能,能够帮助开发者快速构建可靠且易于维护的Web应用程序。本文将详细介绍Django的使用方法,并提供具体实例和代码示例,帮助读者快速上手Django框架。一、安装D

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用