中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Laravel異常上下文解決方案

發布時間:2021-01-21 12:49:11 來源:億速云 閱讀:176 作者:小新 欄目:編程語言

這篇文章主要介紹了Laravel異常上下文解決方案,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

最近項目遇到一個情況,我們在遇到用戶訪問某個信息沒有權限的時候,希望提示詳細的原因,比如當訪問一個團隊資源時非成員訪問的場景下會提示一個:您不是 [xxxxxx] 團隊的成員,暫時無法查看,可<申請加入>,同時需要顯示打碼后的團隊名稱,以及加入按鈕,可是接口方的邏輯是當沒有權限時直接 abort 了:

abort_if(!$user->isMember($resouce->team), 403, '您無權訪問該資源');

得到的響應結果如下:

HTTP/1.0 403 Forbidden{
    "message": "您無權訪問該資源"}

我們不可能將 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(
            [
                'message' => !empty($this->message) ? $this->message : '您無權訪問該資源',
                'team' => [
                    'id' => $this->team->id,
                    'name' => $this->team->desensitised_name,
                ],
            ],
            403
        );
    }
}

這樣一來,我們的邏輯就變成了:

if (!$user->isMember($resouce->team)) {
     throw new NotTeamMemberException($resouce->team, '您無權訪問該資源');
}

當然也可以簡寫為:

\throw_if(!$user->isMember($resouce->team), NotTeamMemberException::class, $resouce->team, '您無權訪問該資源');

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Laravel異常上下文解決方案”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

通城县| 行唐县| 依兰县| 鄂温| 新巴尔虎右旗| 孝感市| 桃园市| 饶平县| 安仁县| 隆尧县| 犍为县| 安阳市| 文成县| 深泽县| 常宁市| 崇信县| 北票市| 新源县| 杭州市| 喀什市| 大港区| 黑河市| 中西区| 阿图什市| 抚松县| 博白县| 富平县| 垣曲县| 阳新县| 扶绥县| 新宁县| 鲁甸县| 绥化市| 敦煌市| 咸丰县| 临汾市| 皋兰县| 元阳县| 兰西县| 栾川县| 酒泉市|