搜索
首页后端开发php教程实例讲解如何在PHP的Yii框架中进行错误和异常处理_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
超越炒作:评估当今PHP的角色超越炒作:评估当今PHP的角色Apr 12, 2025 am 12:17 AM

PHP在现代编程中仍然是一个强大且广泛使用的工具,尤其在web开发领域。1)PHP易用且与数据库集成无缝,是许多开发者的首选。2)它支持动态内容生成和面向对象编程,适合快速创建和维护网站。3)PHP的性能可以通过缓存和优化数据库查询来提升,其广泛的社区和丰富生态系统使其在当今技术栈中仍具重要地位。

PHP中的弱参考是什么?什么时候有用?PHP中的弱参考是什么?什么时候有用?Apr 12, 2025 am 12:13 AM

在PHP中,弱引用是通过WeakReference类实现的,不会阻止垃圾回收器回收对象。弱引用适用于缓存系统和事件监听器等场景,需注意其不能保证对象存活,且垃圾回收可能延迟。

解释PHP中的__ Invoke Magic方法。解释PHP中的__ Invoke Magic方法。Apr 12, 2025 am 12:07 AM

\_\_invoke方法允许对象像函数一样被调用。1.定义\_\_invoke方法使对象可被调用。2.使用$obj(...)语法时,PHP会执行\_\_invoke方法。3.适用于日志记录和计算器等场景,提高代码灵活性和可读性。

解释PHP 8.1中的纤维以进行并发。解释PHP 8.1中的纤维以进行并发。Apr 12, 2025 am 12:05 AM

Fibers在PHP8.1中引入,提升了并发处理能力。1)Fibers是一种轻量级的并发模型,类似于协程。2)它们允许开发者手动控制任务的执行流,适合处理I/O密集型任务。3)使用Fibers可以编写更高效、响应性更强的代码。

PHP社区:资源,支持和发展PHP社区:资源,支持和发展Apr 12, 2025 am 12:04 AM

PHP社区提供了丰富的资源和支持,帮助开发者成长。1)资源包括官方文档、教程、博客和开源项目如Laravel和Symfony。2)支持可以通过StackOverflow、Reddit和Slack频道获得。3)开发动态可以通过关注RFC了解。4)融入社区可以通过积极参与、贡献代码和学习分享来实现。

PHP与Python:了解差异PHP与Python:了解差异Apr 11, 2025 am 12:15 AM

PHP和Python各有优势,选择应基于项目需求。1.PHP适合web开发,语法简单,执行效率高。2.Python适用于数据科学和机器学习,语法简洁,库丰富。

php:死亡还是简单地适应?php:死亡还是简单地适应?Apr 11, 2025 am 12:13 AM

PHP不是在消亡,而是在不断适应和进化。1)PHP从1994年起经历多次版本迭代,适应新技术趋势。2)目前广泛应用于电子商务、内容管理系统等领域。3)PHP8引入JIT编译器等功能,提升性能和现代化。4)使用OPcache和遵循PSR-12标准可优化性能和代码质量。

PHP的未来:改编和创新PHP的未来:改编和创新Apr 11, 2025 am 12:01 AM

PHP的未来将通过适应新技术趋势和引入创新特性来实现:1)适应云计算、容器化和微服务架构,支持Docker和Kubernetes;2)引入JIT编译器和枚举类型,提升性能和数据处理效率;3)持续优化性能和推广最佳实践。

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尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版