Yii2 错误处理

Yii 内置了一个error handler错误处理器,通过 yii\web\ErrorHandler 类实现,它使错误处理更方便, Yii错误处理器做以下工作来提升错误处理效果:

  • 所有非致命PHP错误(如,警告,提示)会转换成可获取异常;
  • 异常和致命的PHP错误会被显示, 在调试模式会显示详细的函数调用栈和源代码行数。
  • 支持使用专用的控制器动作(eg:'site/error')来显示错误;
  • 支持不同的错误响应格式;

error handler 错误处理器默认启用, 可通过在应用的入口脚本中定义常量YII_ENABLE_ERROR_HANDLER来禁用。

注册应用组件:

error handler 注册成一个名称为 errorHandler 应用组件,可以在应用配置(@app/config/main.php)中配置它类似如下:

return [
    'components' => [
        'errorHandler' => [
            'errorAction' => 'site/error',
            'maxSourceLines' => 19,  // 默认值
            'maxTraceSourceLines' => 13,  // 默认值
            'discardExistingOutput' => true,  // 默认值
            'memoryReserveSize' => 262144,  // 默认值
        ],
    ],
];

常用属性:

yii\web\ErrorHandler:
$maxSourceLines        integer // 显示源代码的最大行数, 默认:19;
$maxTraceSourceLines   integer // 显示跟踪源代码行的最大行数, 默认:13;
$errorAction           string  // 用于显示外部错误的控制器动作的路由, eg:'site/error'
$errorView             string  // 未调用堆栈元素时呈现异常和错误的视图文件, 默认:'@yii/views/errorHandler/error.php';
$exceptionView         string  // 呈现异常的视图文件, 默认:'@yii/views/errorHandler/exception.php';
$callStackItemView     string  // 调用堆栈元素时呈现异常和错误的视图文件, 默认:'@yii/views/errorHandler/callStackItem.php';
$previousExceptionView string  // 呈现前一个异常的视图文件, 默认:'@yii/views/errorHandler/previousException.php';
$displayVars           array   // 在错误页面上显示的PHP预定义变量列表, 默认:['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION'];

yii\base\ErrorHandler:
$exception           Exception // 当前正在处理的异常
$memoryReserveSize     integer // 保留内存的大小, 默认:262144;
$discardExistingOutput boolean // 是否在错误显示之前抛弃现有的页面输出, 默认:true;

抛出异常:

use yii\web\NotFoundHttpException;
public function actionView()
{
    throw new NotFoundHttpException('未找到该记录');
}

抛出异常的常用类:

yii\web\HttpException
yii\web\BadRequestHttpException: 400
yii\web\ConflictHttpException: 409
yii\web\ForbiddenHttpException: 403
yii\web\GoneHttpException: 410
yii\web\MethodNotAllowedHttpException: 405
yii\web\NotAcceptableHttpException: 406
yii\web\NotFoundHttpException: 404
yii\web\RangeNotSatisfiableHttpException: 416
yii\web\ServerErrorHttpException: 500
yii\web\TooManyRequestsHttpException: 429
yii\web\UnauthorizedHttpException: 401
yii\web\UnprocessableEntityHttpException: 422
yii\web\UnsupportedMediaTypeHttpException: 415

异常类的使用:

throw new NotFoundHttpException($message = null, $code = 0, Exception $previous = null);
$message  string    // 错误信息
$code     integer   // 错误代码
$previous Exception // 用于异常链接的前一个异常

创建错误处理动作:

namespace app\controllers;
use Yii;
use yii\web\Controller;
class SiteController extends Controller
{
    public function actions()
    {
        return [
            'error' => [
                // 使用 yii\web\ErrorAction 类,渲染 error 视图来显示错误
                'class' => 'yii\web\ErrorAction',
            ],
        ];
    }
    public function actionError()
    {
        $exception = Yii::$app->errorHandler->exception;
        if ($exception !== null) {
            return $this->render('error', ['exception' => $exception]);
        }
    }
}

视图(views/site/error.php)中可以访问的变量:

$name: 错误名称
$message: 错误信息
$exception: 更多详细信息的异常对象,如HTTP 状态码,错误码,错误调用栈等。

如果需要在错误处理程序中重定向,请按以下方式执行:

Yii::$app->getResponse()->redirect($url)->send();
return;