This article mainly introduces how to handle errors and exceptions in the PHP Yii Framework, and focuses on how to use the Error Processor, if you need it, you can refer to Yii that has implemented exception and error toggle on CApplication by default. this is achieved through set_exception_handler and set_error_handler of php. Using these two built-in PHP functions, you can take over uncaptured exceptions and errors in the program to improve the maintainability of the program. This is vital in large systems. When an error occurs, we want to record the relevant details, or even send an alarm in real time to shorten the fault repair time, improve the stability of the entire system.
By default, Yii assigns exception handling to CApplication: handleException, and assigns error handling to CApplication: handleError. However, YII_ENABLE_EXCEPTION_HANDLER can be defined in the entry file, the two constants YII_ENABLE_ERROR_HANDLER are false. the Yii exception and error take-over mechanism is forbidden.
In the following content, exceptions and errors are collectively referred to as errors. if necessary, they are described in detail. The YII_DEBUG constant (false by default, which can be set in the entry file) has an important impact on the display of error messages. in debug mode, the output of errors is the most detailed. Once the program is put into operation, modify YII_DEBUG to false.
Whether in debug mode or not, the Yii program records the error information when generating an error (the error level is error, and the default type is application ). The difference is that detailed information is displayed directly on the web page in debug mode.
CApplication:: handleError($code,$message,$file,$line)
The above method implements the related functions. Pay special attention to the restore_error_handler and restore_exception_handler functions. if the two functions are not called, CApplication will be called when an exception or error occurs again during subsequent error handling :: handleError, which may cause an infinite loop. Therefore, Yii temporarily prohibits CApplication: handleError from taking over subsequent errors and exceptions (using the default php error handling mechanism ), this ensures that loop calls are not generated.
When an error occurs during PHP error processing, what information does PHP record in the log? Error Code (PHP's E_ERROR E_WARNING E_STRICT E_DEPRECATED) message content (for example, Undefined vaiable $ input) generate wrong file path generate wrong row number Additional trace information (this is achieved through debug_backtrace) current URL
In addition to recording the corresponding logs, Yii will also handle subsequent errors (such as interrupted operation and error page display ), by default, errors are handled by the CErrorHandler component (however, you can bind the onError event processor to CApplicaton to implement secondary failover of error handling. the design here is flexible !).
In this case, a CErrorEvent (which includes key parameters $ code, $ message, $ file, and $ line) is generated and passed to the CErrorHandler component for processing. It is handled by CErrorHandler: handleError. This process mainly organizes error-related information and displays it in an appropriate manner.
Whether the debug mode is used (YII_DEBUG = true) has a great impact on the display results of error messages. In debug mode, we want to display detailed error tracking information, while in production mode, we want to display user friendly pages. Therefore, the error display here is different.
When the debug mode is in place, the exception view is rendered incorrectly. Search by the following path:
- Protected/views/system/exception. php
- YII_PATH/views/exception. php
Obviously, the views/system directory is not defined in the application by default, so the view file that comes with the system framework is used. The final file will be views/exception. php in the Yii Framework.
From the above analysis, we can know that in the debugging mode, if we want to use a custom exception page (this may not make much sense ), you need to configure the file protected/views/system/exception. php, the variable that can be used is $ data.
When the system is in non-debug mode, the following processing is performed:
If the errorHandler component defines the errorAction routing information in the configuration file, run it directly. otherwise, run step 1.
Try to load the error view and search by the following path (the first file to be searched will be used)
- 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
Exception handling according to the previous analysis, the exception handling mechanism is similar to the error handling mechanism, and logs are also recorded. the level is error and the classification is "exception. $ EXCEPTIONCLASS ". if the CHttpException class is abnormal, the category name is exception. CHttpException. $ STATUS_CODE. For example, exception. CDbException is used to classify data exceptions.
Next, the error event CExceptionEvent is handled by errorHandler. all error messages are transmitted by the CExceptionEvent object. The solution is as follows:
In debug mode, view files are searched in the following order, and the first file to be searched will be used
- Protected/views/system/exception. php
- YII_PATH/views/exception. php
If it is not in debug mode and the errorAction attribute route is defined for the errorHandler component in the configuration file, run it. otherwise, step 2 is entered.
Try to load the view file in the following order, and the first searched file will be used
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
The flowchart is more clear: the process of searching for view files is important because it is related to the details of how to customize error pages. the subsequent flowchart describes the process in detail.
It can be seen that the easiest way is to set the errorAction attribute for the errorHandler component to specify the route in which an error occurs.
In general, we are most concerned about the display of error pages in production mode. after the above analysis, there are two methods available:
In the configuration file, define the errorAction routing attribute for the errorHandler component (this method should be used first to achieve flexible configuration)
Define any of the following files to customize error pages (not recommended)
- Protected/views/system/zh_cn/error500.php
- Protected/views/system/error500.php
- Protected/views/system/zh_cn/error. php
- Protected/views/system/error. php
1st options: flexible and controllable. you can specify view files in the controller.
Error Processor example
Yii \ web \ ErrorHandler is registered as an application component named errorHandler. you can configure it in application configuration as follows:
return [ 'components' => [ 'errorHandler' => [ 'maxSourceLines' => 20, ], ],];
With the code above, the exception page displays up to 20 source codes.
As mentioned above, the error processor converts all non-fatal PHP errors to a readable exception, that is, the following code can be used to handle PHP errors:
use Yii;use yii\base\ErrorException;try { 10/0;} catch (ErrorException $e) { Yii::warning("Division by zero.");}// execution continues...
If you want to display an error page that tells the user that the request is invalid or cannot be processed, you can simply throw a yii \ web \ HttpException, such as yii \ web \ NotFoundHttpException. The error processor correctly sets the HTTP status code for the response and displays the error information using the appropriate error View page.
use yii\web\NotFoundHttpException;throw new NotFoundHttpException();
Custom error display
The yii \ web \ ErrorHandler Error Processor adjusts the error display according to the value of the constant YII_DEBUG. when YII_DEBUG is true ), the error processor displays exceptions and detailed function call stacks and the number of lines of source code to help debugging. when YII_DEBUG is false, only the error information is displayed to prevent leakage of sensitive information of the application.
Supplement: if the exception inherits yii \ base \ UserException, the function call stack information is not displayed regardless of YII_DEBUG value. this error is considered a user error, developers do not need to modify it.
Yii \ web \ ErrorHandler Error Processor uses two views by default to display errors:
- @ Yii/views/errorHandler/error. php: This view is used to display error messages that do not contain function call stack information. when YII_DEBUG is false, this view is used for all errors.
- @ Yii/views/errorHandler/exception. php: used to display error messages containing function call stack information.
You can configure the yii \ web \ ErrorHandler: errorView and yii \ web \ ErrorHandler: exceptionView attributes of the Error Processor to use the custom error display view.
Incorrect operation
You can use the specified error operation to customize the error display more conveniently. to do this, first configure the yii \ web \ errorHandler: errorAction attribute of the ErrorHandler component, as shown below:
return [ 'components' => [ 'errorHandler' => [ 'errorAction' => 'site/error', ], ]];
The yii \ web \ ErrorHandler: errorAction attribute is routed to an operation. the preceding configuration indicates that errors of function call stack information are not displayed and will be displayed by executing the site/error operation.
You can create a site or error as follows:
namespace app\controllers;use Yii;use yii\web\Controller;class SiteController extends Controller{ public function actions() { return [ 'error' => [ 'class' => 'yii\web\ErrorAction', ], ]; }}
The code above defines that the error operation uses the yii \ web \ ErrorAction class, which renders the class named error View to display the error.
In addition to yii \ web \ ErrorAction, you can define an error operation using a method similar to the following:
public function actionError(){ $exception = Yii::$app->errorHandler->exception; if ($exception !== null) { return $this->render('error', ['exception' => $exception]); }}
Now you should create a view file named views/site/error. php. In this view file, if the incorrect operation is defined as yii \ web \ ErrorAction, you can access the following variables defined in this operation:
- Name: incorrect name
- Message: Error message
- Exception: exception objects with more details, such as HTTP status codes, error codes, and error call stacks.
Supplement: If you use a basic or advanced application template, the error operation and error view are defined.
Custom error format
The error processor displays the error according to the format set for the Response. if the yii \ web \ Response: format Response format is html, the error or exception view is used to display the error message, as described in the previous section. For other Response formats, the error processor assigns an error message as an array to the yii \ web \ Response: data attribute and converts it to the corresponding format. for example, if the Response format is json, the following response information is displayed:
HTTP/1.1 404 Not FoundDate: Sun, 02 Mar 2014 05:31:43 GMTServer: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8yTransfer-Encoding: chunkedContent-Type: application/json; charset=UTF-8{ "name": "Not Found Exception", "message": "The requested resource was not found.", "code": 0, "status": 404}
You can customize the error response format by responding to the beforeSend event of the response component in the application configuration.
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; } }, ], ],];
The above code will reformat the error response, similar to the following:
HTTP/1.1 200 OKDate: Sun, 02 Mar 2014 05:31:43 GMTServer: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8yTransfer-Encoding: chunkedContent-Type: application/json; charset=UTF-8{ "success": false, "data": { "name": "Not Found Exception", "message": "The requested resource was not found.", "code": 0, "status": 404 }}