ホームページ >バックエンド開発 >PHPチュートリアル >PHP の Yii フレームワークでエラーと例外を処理する方法を説明する例、yii_PHP チュートリアルを説明する例
Yii は、デフォルトで CApplication に例外とエラーの引き継ぎを実装しています。これは、PHP の set_Exception_handler と set_error_handler によって実現されます。これら 2 つの PHP 組み込み関数により、プログラム内で捕捉されなかった例外やエラーを引き継ぐことができ、プログラムの保守性が向上します。これは大規模システムでは非常に重要であり、エラーが発生した場合、関連する詳細情報を記録し、すぐにアラームを送信することで、障害修復時間を短縮し、システム全体の安定性を向上させることができます。
デフォルトでは、Yii は例外処理を CApplication::handleException に割り当て、エラー処理を CApplication::handleError に割り当てますが、エントリ ファイル内の 2 つの定数 YII_ENABLE_EXCEPTION_HANDLER と YII_ENABLE_ERROR_HANDLER を false メカニズムとして定義することで、Yii の例外処理とエラー引き継ぎの使用を無効にすることができます。 。
以下のコンテンツでは、例外とエラーを総称してエラーと呼び、必要に応じて詳細に区別します。 YII_DEBUG 定数 (デフォルトは false、エントリ ファイルで設定可能) は、デバッグ モードでのエラー出力が最も詳細に表示されることに非常に重要な影響を与えます。プログラムが動作を開始したら、YII_DEBUG を false に変更する必要があります。
デバッグモードであるかどうかに関係なく、Yii プログラムがエラーを生成すると、関連するエラー情報が記録されます (エラーレベルはエラー、デフォルトのカテゴリはアプリケーションです)。違いは、デバッグ モードでは、詳細情報が Web ページに直接表示されることです。
上記のメソッドは、関連するロジックを実装します。この 2 つの関数が呼び出されないと、後続のエラー処理プロセス中に例外またはエラーが再度発生すると、CApplication:: handleError が再度呼び出され、無限ループが発生する可能性があるため、特に注意してください。したがって、Yii は、(PHP のデフォルトのエラー処理メカニズムを使用して) 後続のエラーと例外を引き継ぐための CApplication::handleError の使用を一時的に禁止し、ループ呼び出しが発生しないようにします。
PHP エラー処理 エラーが発生した場合、PHP はどのような情報をログに記録しますか?エラー コード (つまり、PHP の E_ERROR E_WARNING E_STRICT E_DEPRECATED) メッセージの内容 (例: Unknown vaiable $input) エラーを生成したファイル パス エラーを生成した行番号 追加の追跡バックトレース情報 (これは debug_backtrace によって取得されます) 現在の URL
対応するログを記録することに加えて、Yii はエラーに対する後続の処理 (実行の中断、エラーページの表示など) も実行します。デフォルトでは、エラー処理は CErrorHandler コンポーネントに引き渡されます (ただし、onError イベントをバインドすることもできます)。ハンドラーから CApplicton へのこの設計は、エラー処理の二次的な引き継ぎを実装するために非常に柔軟です!)。
この時点で、CErrorEvent ($code、$message、$file、$line などのいくつかの重要なパラメーターを含む) が生成され、処理のために CErrorHandler コンポーネントに渡されます。具体的には、CErrorHandler::handleError によって処理されます。このプロセスは主に、エラー関連の情報を整理し、適切な方法で表示するために行われます。
デバッグ モード (YII_DEBUG==true) かどうかは、エラー メッセージの表示に大きな影響を与えます。デバッグ モードでは詳細なエラー追跡情報を表示する必要があり、実稼働モードではユーザー フレンドリーなページを表示する必要があります。したがって、ここでのエラー表示が異なりますので、その違いについて以下に説明します。
デバッグ モードでは、例外ビューが直接レンダリングされてエラーが表示されます。次のパスで検索します:
明らかに、views/system ディレクトリはデフォルトではアプリケーションに定義されていないため、システム フレームワークに付属のビュー ファイルが使用されます。最後にインクルードされるファイルは、Yii フレームワークの views/Exception.php になります。
上記の分析から、デバッグ モードでカスタム例外ページを使用したい場合 (通常、これはあまり意味がありません)、ファイル protected/views/system/Exception.php を設定する必要があることがわかります。使用できる変数 それが $data です。
非デバッグモードの場合、次の処理が行われます:
errorAction ルーティング情報が構成ファイル内の errorHandler コンポーネントに定義されている場合は、それを直接実行します。それ以外の場合は、ステップ 2 に進みます。
エラービューをロードして、次のパスに従って検索してみてください (最初に検索されたファイルが使用されます)
例外処理 前述の分析によると、例外処理メカニズムはエラー処理メカニズムと同様であり、CHttpException クラスの例外の場合、レベルはエラー、分類は「Exception.$EXCEPTIONCLASS」になります。分類名は、Exception.CHttpException です。たとえば、データの例外分類は、Exception.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 } }