ホームページ  >  記事  >  PHPフレームワーク  >  Laravel例外コンテキストソリューションを共有する

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

藏色散人
藏色散人転載
2021-01-21 11:05:061952ブラウズ

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

最近、プロジェクトで問題が発生しました。特定の情報へのアクセス権限を持たないユーザーに遭遇した場合、詳細な理由を提示したいと考えています。たとえば、チーム リソースへのアクセスやメンバー以外のアクセスの場合などです。 あなたは [xxxxxx] チームのメンバーではないため、一時的に表示できません。167efbafb4040cbe9c8cfcc2ecb3e2eb できます。同時に、コード化されたチーム名と参加ボタンを表示する必要がありますが、インターフェースのロジックとしては権限がありません。その際、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, '您无权访问该资源');
+ if (!$user->isMember($resouce->team)) {
+    return response()->json([
+        'message' => '您无权访问该资源',
+        'team' => [
+            'id' => $resouce->team_id,
+            'name'=> $resouce->team->desensitised_name,
+        ]
+    ], 403);
+ }

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

最適化の実装

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

 if (!$user->isMember($resouce->team)) {
    abort(response()->json([
        'message' => '您无权访问该资源',
        'team' => [
            'id' => $resouce->team_id,
            'name'=> $resouce->team->desensitised_name,
        ]
    ], 403));
 }

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

論理再利用

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

public function render($request, Throwable $e)
{
    if (method_exists($e, 'render') && $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 までご連絡ください。