Laravel例外コンテキストソリューションを共有する

藏色散人
リリース: 2021-01-22 09:05:13
転載
1963 人が閲覧しました

次のコラムでは、Laravel チュートリアル コラムの Laravel 例外コンテキスト ソリューションを紹介します。困っている友人の役に立てば幸いです。

最近、プロジェクトで問題が発生しました。特定の情報へのアクセス権限を持たないユーザーに遭遇した場合、詳細な理由を提示したいと考えています。たとえば、チーム リソースへのアクセスやメンバー以外のアクセスの場合などです。 あなたは [xxxxxx] チームのメンバーではないため、一時的に表示できません。<参加を申請> できます。同時に、コード化されたチーム名と参加ボタンを表示する必要がありますが、インターフェースのロジックとしては権限がありません。その際、abort を直接実行しました:

abort_if(!$user->isMember($resouce->team), 403, '您无权访问该资源');
ログイン後にコピー

得られた応答結果は次のとおりです:

HTTP/1.0 403 Forbidden{
    "message": "您无权访问该资源"}
ログイン後にコピー

HTML を使用してフロントエンド プロンプト ページを表示することは不可能です。これは結合されすぎます。強力で、フロント エンドとバック エンドの分離の原則に違反します。私たちの目標は、問題を解決するために次の形式を返すことです:

HTTP/1.0 403 Forbidden{
    "message": "您无权访问该资源",
    "team": {
        "id": "abxT8sioa0Ms",
        "name": "CoDesign****"
    }}
ログイン後にコピー

コンテキストを保持してデータを渡すことで、フロントエンドの学生が自由に組み合わせることが容易になります。

変換の開始

もちろん、これは複雑な問題ではなく、元の abort_if を直接変更することで解決できます。 :

- abort_if(!$user->isMember($resouce->team), 403, &#39;您无权访问该资源&#39;);
+ if (!$user->isMember($resouce->team)) {
+    return response()->json([
+        &#39;message&#39; => &#39;您无权访问该资源&#39;,
+        &#39;team&#39; => [
+            &#39;id&#39; => $resouce->team_id,
+            &#39;name&#39;=> $resouce->team->desensitised_name,
+        ]
+    ], 403);
+ }
ログイン後にコピー

これで問題は解決したように見えますが、想像してみてください。クロージャで例外が検出され、終了したい場合、上記の return スタイルの記述は次のようになります。結局のところ、return は最新のコンテキスト環境を終了するだけであり、abort のようにアプリケーション全体の実行を終了してから、別の変換を実行したいと考えています。 。

最適化の実装

abort ソース コードを読んだ後、その最初のパラメータが実際に をサポートしていることがわかりました。 \Symfony\Component\HttpFoundation\Response インスタンス、および上記の return の結果がそのインスタンスであるため、これを次のように変更するだけで済みます:

 if (!$user->isMember($resouce->team)) {
    abort(response()->json([
        &#39;message&#39; => &#39;您无权访问该资源&#39;,
        &#39;team&#39; => [
            &#39;id&#39; => $resouce->team_id,
            &#39;name&#39;=> $resouce->team->desensitised_name,
        ]
    ], 403));
 }
ログイン後にコピー

次のようになります。異常中断を実装したのですが、新たな問題が発生しました 再利用するのはやはり恥ずかしいです この許可を判定する箇所でこのコードが繰り返し登場することになります これは我々が望んでいることではありません

論理再利用

論理再利用を実現するために、\App\Exceptions\Handler の実装を調べ、## を見つけました。親クラスの #render メソッドも次のような設計になっています:

public function render($request, Throwable $e)
{
    if (method_exists($e, &#39;render&#39;) && $response = $e->render($request)) {
        return Router::toResponse($request, $response);
    } elseif ($e instanceof Responsable) {
        return $e->toResponse($request);
    }
    //...
ログイン後にコピー

したがって、このロジックを独立した例外クラスに抽出し、

render メソッドを実装できます:

最初に例外クラスを作成します:

$ ./artisan make:exception NotTeamMemberException
ログイン後にコピー

実装コードは次のとおりです:

<?php
namespace App\Exceptions;
use App\Team;
class NotTeamMemberException extends \Exception
{
    public Team $team;
    public function __construct(Team $team, $message = "")
    {
        $this->team = $team;
        parent::__construct($message, 403);
    }
    public function render()
    {
        return response()->json(
            [
                &#39;message&#39; => !empty($this->message) ? $this->message : &#39;您无权访问该资源&#39;,
                &#39;team&#39; => [
                    &#39;id&#39; => $this->team->id,
                    &#39;name&#39; => $this->team->desensitised_name,
                ],
            ],
            403
        );
    }
}
ログイン後にコピー

このようにして、ロジックは次のようになります:

if (!$user->isMember($resouce->team)) {
     throw new NotTeamMemberException($resouce->team, &#39;您无权访问该资源&#39;);
}
ログイン後にコピー

もちろんそれは略語は次のとおりです:

\throw_if(!$user->isMember($resouce->team), NotTeamMemberException::class, $resouce->team, &#39;您无权访问该资源&#39;);
ログイン後にコピー
この問題は、最終的に比較的完璧な方法で解決されました。より良い解決策がある場合は、コメントして議論してください。

以上がLaravel例外コンテキストソリューションを共有するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:learnku.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート