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이며 항목 파일에서 설정할 수 있음)는 오류 정보 표시에 매우 중요한 영향을 미칩니다. 디버그 모드에서는 오류 출력이 가장 상세합니다. 프로그램이 실행되면 YII_DEBUG를 false로 수정해야 합니다.
디버그 모드 여부에 관계없이 Yii 프로그램에서 오류가 발생하면 관련 오류 정보가 기록됩니다(오류 수준은 오류, 기본 범주는 응용 프로그램). 차이점은 디버그 모드에서는 자세한 정보가 웹 페이지에 직접 표시된다는 것입니다.
CApplication:: handleError($code,$message,$file,$line)
위 메소드는 관련 로직을 구현합니다. 이 두 함수가 호출되지 않으면 후속 오류 처리 과정에서 예외나 오류가 다시 발생하면 CApplication::handlerError가 다시 호출되어 무한 루프가 발생할 수 있습니다. 따라서 Yii는 일시적으로 CApplication::handleError를 사용하여 후속 오류 및 예외를 처리하는 것을 금지합니다(PHP의 기본 오류 처리 메커니즘 사용). 이를 통해 루프 호출이 발생하지 않도록 합니다.
PHP 오류 처리 오류가 발생하면 PHP는 어떤 정보를 로그에 기록합니까? 오류 코드(예: PHP의 E_ERROR E_WARNING E_STRICT E_DEPRECATED) 메시지 내용(예: 정의되지 않은 vaiable $input) 오류를 생성한 파일 경로 오류를 생성한 줄 번호 추가 추적 역추적 정보(debug_backtrace를 통해 얻음) 현재 URL
해당 로그를 기록하는 것 외에도 Yii는 오류에 대한 후속 처리(예: 실행 중단, 오류 페이지 표시 등)도 수행합니다. 기본적으로 오류 처리는 CErrorHandler 구성 요소에 전달됩니다(그러나 onError 이벤트를 바인딩할 수 있습니다). CApplicaton에 대한 처리기 여기 디자인은 오류 처리의 보조 인수를 구현하는 데 매우 유연합니다!).
이때 CErrorEvent($code, $message, $file 및 $line과 같은 여러 주요 매개변수 포함)가 생성되어 처리를 위해 CErrorHandler 구성 요소에 전달됩니다. 특히 CErrorHandler::handleError에 의해 처리됩니다. 이 프로세스는 주로 오류 관련 정보를 구성하고 적절한 방식으로 표시하는 것입니다.
디버그 모드(YII_DEBUG==true)인지 여부는 오류 메시지 표시에 큰 영향을 미칩니다. 디버깅 모드에서는 자세한 오류 추적 정보를 표시하고, 프로덕션 모드에서는 사용자에게 친숙한 페이지를 표시하려고 합니다. 따라서 여기의 오류 표시는 다르며, 차이점은 아래에 설명되어 있습니다.
디버그 모드에서는 예외 보기가 직접 렌더링되어 오류를 표시합니다. 다음 경로로 검색합니다:
분명히 views/system 디렉터리는 기본적으로 애플리케이션에 정의되어 있지 않으므로 시스템 프레임워크와 함께 제공되는 보기 파일이 사용됩니다. 최종 포함 파일은 Yii 프레임워크의 views/Exception.php입니다.
위 분석을 통해 디버깅 모드에서 사용자 정의 예외 페이지를 사용하려면(일반적으로 별 의미가 없을 수 있음) protected/views/system/Exception.php 파일을 구성해야 한다는 것을 알 수 있습니다. 변수는 $data입니다.
비디버깅 모드에서는 다음 처리가 수행됩니다:
구성 파일에 errorHandler 컴포넌트에 errorAction 라우팅 정보가 정의되어 있으면 직접 실행하고, 그렇지 않으면 2단계로 진행하세요.
에러뷰를 로드하여 다음 경로에 따라 검색해 보세요. (첫 번째 검색된 파일이 사용됩니다.)
예외 처리 이전 분석에 따르면 예외 처리 메커니즘은 오류 처리 메커니즘과 유사하며, 수준은 error이고 분류는 CHttpException 클래스인 경우입니다. 예외의 경우 분류 이름은 CHttpException.$STATUS_CODE입니다. 예를 들어, 데이터의 예외 분류를 예외.CDbException이라고 합니다.
다음으로, 오류 이벤트 CExceptionEvent가 처리를 위해 errorHandler로 전달되고, 모든 오류 정보는 CExceptionEvent 객체에 의해 전달됩니다. 처리방법은 다음과 같습니다.
디버그 모드에서는 다음 순서로 뷰 파일을 검색하며, 먼저 검색된 파일을 사용합니다
비디버깅 모드이고 구성 파일의 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 } }