Laravel コア分析の例外処理 (コード)
この記事の内容は、Laravel コア解析の例外処理 (コード) に関するものです。必要な方は参考にしていただければ幸いです。
例外処理は、プログラムの実行時エラーを処理するメカニズムを開発者に提供する非常に重要ですが、プログラム自体の詳細は次のとおりです。ユーザーに提供され、開発者に完全なエラー トレースバック スタックを提供すると同時に、プログラムの堅牢性も向上します。
この記事では、Laravel で提供される例外処理機能を簡単に確認し、その後、開発での例外処理の使用方法、カスタム例外の使用方法、Laravel の例外処理機能を拡張する方法について説明します。
例外ハンドラーの登録
ここでは、ブートストラップ ステージで何度も述べたように、カーネルがリクエストを処理する前にブートストラップ ステージに戻る必要があります。 Foundation\Bootstrap\ HandleExceptions セクションで、Laravel はシステム例外処理動作を設定し、グローバル例外ハンドラーを登録します。
class HandleExceptions { public function bootstrap(Application $app) { $this->app = $app; error_reporting(-1); set_error_handler([$this, 'handleError']); set_exception_handler([$this, 'handleException']); register_shutdown_function([$this, 'handleShutdown']); if (! $app->environment('testing')) { ini_set('display_errors', 'Off'); } } public function handleError($level, $message, $file = '', $line = 0, $context = []) { if (error_reporting() & $level) { throw new ErrorException($message, 0, $level, $file, $line); } } }
set_Exception_handler([$this, 'handleException']) は、HandleExceptions の handleException メソッドをグローバルとして登録します。プログラムのハンドラー メソッド:
public function handleException($e) { if (! $e instanceof Exception) { $e = new FatalThrowableError($e); } $this->getExceptionHandler()->report($e); if ($this->app->runningInConsole()) { $this->renderForConsole($e); } else { $this->renderHttpResponse($e); } } protected function getExceptionHandler() { return $this->app->make(ExceptionHandler::class); } // 渲染CLI请求的异常响应 protected function renderForConsole(Exception $e) { $this->getExceptionHandler()->renderForConsole(new ConsoleOutput, $e); } // 渲染HTTP请求的异常响应 protected function renderHttpResponse(Exception $e) { $this->getExceptionHandler()->render($this->app['request'], $e)->send(); }
プロセッサでは、例外は主に ExceptionHandler のレポート メソッドを通じて報告されます。ここでは、例外は storage/laravel.log ファイルに記録され、それに応じて例外応答がレンダリングされます。リクエスト タイプに変更して、クライアントへの出力を生成します。ここでの ExceptionHandler は \App\Exceptions\Handler クラスのインスタンスであり、プロジェクトの先頭でサービス コンテナに登録されます。
// bootstrap/app.php /* |-------------------------------------------------------------------------- | Create The Application |-------------------------------------------------------------------------- */ $app = new Illuminate\Foundation\Application( realpath(__DIR__.'/../') ); /* |-------------------------------------------------------------------------- | Bind Important Interfaces |-------------------------------------------------------------------------- */ ...... $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class );
ちなみに、ここでは set_error_handler 関数を使用して登録します。エラー ハンドラー。一部の古いコードやクラス ライブラリでは、例外ハンドラーは例外のみを処理でき、エラーは処理できないため、通常は set_error_handler が使用されます。グローバル エラー ハンドラー メソッドを登録し、メソッド内でエラーをキャッチした後、エラーを例外に変換して再スローすることで、プロジェクト内のすべてのコードが正しく実行されなかった場合に例外インスタンスをスローできるようになります。
/** * Convert PHP errors to ErrorException instances. * * @param int $level * @param string $message * @param string $file * @param int $line * @param array $context * @return void * * @throws \ErrorException */ public function handleError($level, $message, $file = '', $line = 0, $context = []) { if (error_reporting() & $level) { throw new ErrorException($message, 0, $level, $file, $line); } }
一般的に使用される Laravel 例外の例
Laravel は、一般的なプログラム例外に対応する例外インスタンスをスローします。これにより、開発者はこれらのランタイム例外をキャッチし、次に従ってフォローアップ処理を行うことができます。あなた自身のニーズ (例: catch で別の修復メソッドを呼び出す、例外をログ ファイルに記録する、アラーム メールやテキスト メッセージを送信する)
ここでは、開発中によく発生するいくつかの例外をリストし、その内容について説明します。通常のコーディングでは、プログラム内でこれらの例外をキャッチすることに注意し、それらを適切に処理してプログラムをより堅牢にする必要があります。
Illuminate\Database\QueryException この例外は、Laravel で SQL ステートメントを実行するときにエラーが発生したときにスローされます。これは最も一般的に使用される例外でもあり、たとえば、多くの人が SQL 実行エラーをキャプチャするために使用されます。 Update ステートメントの実行時に SQL を判断するのと同様に、実行後に変更された行の数が判断され、UPDATE が成功したかどうかが判断されます。ただし、一部のシナリオでは、実行された UPDATE ステートメントはレコード値を変更しません。また、トランザクションの実行中に QueryException がキャッチされた場合、トランザクションはキャッチ コード ブロックでロールバックされる可能性があります。
Illuminate\Database\Eloquent\ModelNotFoundException この例外は、モデルの findOrFail メソッドと firstOrFail メソッドで 1 つのレコードが見つからない場合にスローされます (データが見つからない場合、find と first は NULL を返します)。
Illuminate\Validation\ValidationException この例外は、リクエストが Laravel の FormValidator 検証に合格しない場合にスローされます。
Illuminate\Auth\Access\AuthorizationException この例外は、ユーザーリクエストが Laravel のポリシー (ポリシー) 検証に合格しない場合にスローされます。
Symfony\Component\Routing\Exception\MethodNotAllowedException ルーティングをリクエストするとき、 HTTP メソッドが正しくありません
Illuminate\Http\Exceptions\HttpResponseException Laravel は、HTTP リクエストの処理が失敗したときにこの例外をスローします
Laravel の例外ハンドラーを拡張します
# 前述したように、Laravel は \App\Exceptions\Handler をグローバル例外ハンドラーとして正常に登録しました。コード内でキャッチされなかった例外は、最終的には \App\Exceptions\Handler によってキャッチされます。次に、例外応答をレンダリングし、クライアントに応答を送信します。ただし、組み込みの例外ハンドラー メソッドは使いにくいことがよくあります。次の例では、Sentry システムに例外を報告します。これは非常に優れたエラー収集サービスです。使用:public function report(Exception $exception) { if (app()->bound('sentry') && $this->shouldReport($exception)) { app('sentry')->captureException($exception); } parent::report($exception); }
JOSN 形式とは異なることが多いため、レンダリングをカスタマイズする必要があります。方法。
public function render($request, Exception $exception) { //如果客户端预期的是JSON响应, 在API请求未通过Validator验证抛出ValidationException后 //这里来定制返回给客户端的响应. if ($exception instanceof ValidationException && $request->expectsJson()) { return $this->error(422, $exception->errors()); } if ($exception instanceof ModelNotFoundException && $request->expectsJson()) { //捕获路由模型绑定在数据库中找不到模型后抛出的NotFoundHttpException return $this->error(424, 'resource not found.'); } if ($exception instanceof AuthorizationException) { //捕获不符合权限时抛出的 AuthorizationException return $this->error(403, "Permission does not exist."); } return parent::render($request, $exception); }
自定义后,在请求未通过FormValidator验证时会抛出ValidationException, 之后异常处理器捕获到异常后会把错误提示格式化为项目统一的JSON响应格式并输出给客户端。这样在我们的控制器中就完全省略了判断表单验证是否通过如果不通过再输出错误响应给客户端的逻辑了,将这部分逻辑交给了统一的异常处理器来执行能让控制器方法瘦身不少。
使用自定义异常
这部分内容其实不是针对Laravel框架自定义异常,在任何项目中都可以应用我这里说的自定义异常。
我见过很多人在Repository或者Service类的方法中会根据不同错误返回不同的数组,里面包含着响应的错误码和错误信息,这么做当然是可以满足开发需求的,但是并不能记录发生异常时的应用的运行时上下文,发生错误时没办法记录到上下文信息就非常不利于开发者进行问题定位。
下面的是一个自定义的异常类
namespace App\Exceptions\; use RuntimeException; use Throwable; class UserManageException extends RuntimeException { /** * The primitive arguments that triggered this exception * * @var array */ public $primitives; /** * QueueManageException constructor. * @param array $primitives * @param string $message * @param int $code * @param Throwable|null $previous */ public function __construct(array $primitives, $message = "", $code = 0, Throwable $previous = null) { parent::__construct($message, $code, $previous); $this->primitives = $primitives; } /** * get the primitive arguments that triggered this exception */ public function getPrimitives() { return $this->primitives; } }
定义完异常类我们就能在代码逻辑中抛出异常实例了
class UserRepository { public function updateUserFavorites(User $user, $favoriteData) { ...... if (!$executionOne) { throw new UserManageException(func_get_args(), 'Update user favorites error', '501'); } ...... if (!$executionTwo) { throw new UserManageException(func_get_args(), 'Another Error', '502'); } return true; } } class UserController extends ... { public function updateFavorites(User $user, Request $request) { ....... $favoriteData = $request->input('favorites'); try { $this->userRepo->updateUserFavorites($user, $favoritesData); } catch (UserManageException $ex) { ....... } } }
除了上面Repository列出的情况更多的时候我们是在捕获到上面列举的通用异常后在catch代码块中抛出与业务相关的更细化的异常实例方便开发者定位问题,我们将上面的updateUserFavorites 按照这种策略修改一下
public function updateUserFavorites(User $user, $favoriteData) { try { // database execution // database execution } catch (QueryException $queryException) { throw new UserManageException(func_get_args(), 'Error Message', '501' , $queryException); } return true; }
在上面定义UserMangeException类的时候第四个参数$previous是一个实现了Throwable接口类实例,在这种情景下我们因为捕获到了QueryException的异常实例而抛出了UserManagerException的实例,然后通过这个参数将QueryException实例传递给PHP异常的堆栈,这提供给我们回溯整个异常的能力来获取更多上下文信息,而不是仅仅只是当前抛出的异常实例的上下文信息, 在错误收集系统可以使用类似下面的代码来获取所有异常的信息。
while($e instanceof \Exception) { echo $e->getMessage(); $e = $e->getPrevious(); }
异常处理是PHP非常重要但又容易让开发者忽略的功能,这篇文章简单解释了Laravel内部异常处理的机制以及扩展Laravel异常处理的方式方法。更多的篇幅着重分享了一些异常处理的编程实践,这些正是我希望每个读者都能看明白并实践下去的一些编程习惯,包括之前分享的Interface的应用也是一样。
以上がLaravel コア分析の例外処理 (コード)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











session_start()への複数の呼び出しにより、警告メッセージと可能なデータ上書きが行われます。 1)PHPは警告を発し、セッションが開始されたことを促します。 2)セッションデータの予期しない上書きを引き起こす可能性があります。 3)session_status()を使用してセッションステータスを確認して、繰り返しの呼び出しを避けます。

AIは、作曲家の使用を最適化するのに役立ちます。特定の方法には次のものが含まれます。1。依存関係管理の最適化:AIは依存関係を分析し、最適なバージョンの組み合わせを推奨し、競合を減らします。 2。自動コード生成:AIは、ベストプラクティスに準拠したComposer.jsonファイルを生成します。 3.コードの品質を改善する:AIは潜在的な問題を検出し、最適化の提案を提供し、コードの品質を向上させます。これらの方法は、開発者が効率とコードの品質を向上させるのに役立つ機械学習および自然言語処理技術を通じて実装されています。

session_start()iscrucialinphpformangingusersions.1)itInitiateSanewsessionifnoneExists、2)resumesanexistingsession、および3)SetSessionCookieforcontinuityAcrossRequests、ApplicationslicationSliviseSlikeUserauthicationAnticatent。

LaravelとYiiの主な違いは、デザインの概念、機能的特性、使用シナリオです。 1.Laravelは、開発のシンプルさと喜びに焦点を当てており、迅速な開発や初心者に適したEloquentormやArtisan Toolsなどの豊富な機能を提供します。 2.YIIはパフォーマンスと効率を強調し、高負荷アプリケーションに適しており、効率的なActiverCordおよびキャッシュシステムを提供しますが、急な学習曲線があります。

Laravel10の最新バージョンは、MySQL 5.7以降、PostgreSQL 9.6以降、SQLite 3.8.8以降、SQLServer 2017以降と互換性があります。これらのバージョンは、クエリとストレージの効率を向上させるMySQL5.7のJSONデータ型など、LaravelのORM機能をサポートするため選択されます。

HTML5は5つの重要な改善をもたらします。1。セマンティックタグにより、コードの明確性とSEO効果が向上します。 2.マルチメディアサポートは、ビデオとオーディオの埋め込みを簡素化します。 3。フォームエンハンスメントは、検証を簡素化します。 4.オフラインおよびローカルストレージにより、ユーザーエクスペリエンスが向上します。 5。キャンバスとグラフィック機能は、Webページの視覚化を強化します。

MySQL関数は、データ処理と計算に使用できます。 1.基本的な使用には、文字列処理、日付計算、数学操作が含まれます。 2。高度な使用法には、複数の関数を組み合わせて複雑な操作を実装することが含まれます。 3.パフォーマンスの最適化では、Where句での機能の使用を回避し、GroupByおよび一時テーブルを使用する必要があります。

2024年の必須のLaravel拡張パッケージには、次のものが含まれます。 2。LaravelteLescope、詳細なアプリケーション監視を提供します。 3。RARAVELHORIZON、Redisキュータスクの管理。これらの拡張パックは、開発効率とアプリケーションのパフォーマンスを向上させることができます。
