Home >Backend Development >PHP Tutorial >Examples to explain how to handle errors and exceptions in PHP's Yii framework, examples to explain yii_PHP tutorial
Yii has implemented exception and error takeover on CApplication by default. This is This is achieved through php's set_exception_handler and set_error_handler. Through these two PHP built-in functions, uncaught exceptions and errors in the program can be taken over, thereby improving the maintainability of the program. This is crucial in large systems. When an error occurs, we hope to record relevant detailed information and even send an alarm immediately, thereby shortening the fault repair time and improving the stability of the entire system.
By default, Yii will assign exception handling to CApplication::handleException and error handling to CApplication::handleError, but you can disable the use of Yii's exception and error takeover by defining the two constants YII_ENABLE_EXCEPTION_HANDLER and YII_ENABLE_ERROR_HANDLER in the entry file as false. mechanism.
In the following content, exceptions and errors are collectively referred to as errors, and detailed distinctions will be made if necessary. The YII_DEBUG constant (defaults to false, which can be set in the entry file) has a very important impact on the display of error information. In debug mode, the error output is the most detailed. Once the program is put into operation, YII_DEBUG should be modified to false.
Regardless of whether it is in debug mode or not, when the Yii program generates an error, the relevant error information will be recorded (the error level is error, and the default category is application). The difference is that in debug mode, detailed information will be displayed directly on the web page.
CApplication:: handleError($code,$message,$file,$line)
The above method implements relevant logic. Pay special attention to the restore_error_handler and restore_exception_handler functions. If these two functions are not called, then during the subsequent error handling process, when an exception or error occurs again, CApplication:: handleError will be called again, which may cause an infinite loop. Therefore, Yii temporarily prohibits the use of CApplication::handleError to take over subsequent errors and exceptions (using PHP's default error handling mechanism), which ensures that no loop calls will occur.
PHP error handling When an error occurs, what information does PHP record in the log? Error code (i.e. PHP's E_ERROR E_WARNING E_STRICT E_DEPRECATED) Message content (e.g. Undefined vaiable $input) The file path that produced the error The line number that produced the error Additional tracking backtrace information (this is achieved through debug_backtrace) Current URL
In addition to recording corresponding logs, Yii will also perform subsequent processing on errors (such as interrupting execution, displaying error pages, etc.). By default, error handling will be handed over to the CErrorHandler component (but you can bind the onError event handler to CApplicaton The design here is very flexible to implement secondary takeover of error handling!).
At this time, a CErrorEvent (and containing several key parameters such as $code, $message, $file, and $line) will be generated and passed to the CErrorHandler component for processing. Specifically, it is handled by CErrorHandler::handleError. This process is mainly to organize error-related information and display it in an appropriate way.
Whether it is in debug mode (YII_DEBUG==true) has a great impact on the display of error messages. In debug mode we want to display detailed error tracking information, while in production mode we want to display a user-friendly page. Therefore, the error display here is different, and the differences are explained below.
When in debug mode, the exception view will be rendered directly to display errors. Will search by the following path:
Obviously, the views/system directory is not defined in the application by default, so the view files that come with the system framework will be used. The final included file will be views/exception.php from the Yii framework.
From the above analysis, we can know that if we want to use a custom exception page in debugging mode (generally this may not make much sense), we need to configure the file protected/views/system/exception.php, which can be used The variable is $data.
When in non-debugging mode, the following processing will be done:
If the errorAction routing information is defined for the errorHandler component in the configuration file, run it directly, otherwise proceed to step 2.
Try to load the error view and search according to the following path (the first searched file will be used)
Exception handling According to the previous analysis, the exception handling mechanism is similar to the error handling mechanism. Logs will also be recorded. The level is error and the classification is "exception.$EXCEPTIONCLASS". If it is a CHttpException class exception, the classification name is exception. CHttpException.$STATUS_CODE. For example, the exception classification of data is called exception.CDbException.
Next, the error event CExceptionEvent is handed over to the errorHandler for processing, and all error information is passed by the CExceptionEvent object. The processing method is as follows:
如果是调试模式,则按以下顺序搜索视图文件,第一个搜索到的文件将被使用
如果是非调试模式,并在配置文件中为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
使用流程图描述,会更清楚一些:搜寻视图文件流程比较重要,因为它关系到我们如何自定义错误页面的细节问题,后续的流程图详细描述其过程。
从图中可以看出,最容易的方式还是给errorHandler组件设置errorAction属性指定错误发生的路由
一般而言,我们最关心的是生产模式下错误页面的显示问题,经过以上分析,有两种方法可用:
配置文件中为errorHandler组件定义errorAction路由属性(应该优先使用这个方式,以达到灵活配置目的)
定义以下文件中的任意一个,实现自定义错误页(不推荐)
第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\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, 可以访问该操作中定义的如下变量:
补充: 如果你使用 基础应用模板 或 高级应用模板, 错误操作和错误视图已经定义好了。
自定义错误格式
错误处理器根据响应设置的格式来显示错误, 如果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 } }