Maison >cadre php >Laravel >Partager une solution de contexte d'exception Laravel

Partager une solution de contexte d'exception Laravel

藏色散人
藏色散人avant
2021-01-21 11:05:061980parcourir
Vous trouverez ci-dessous

Tutoriel Laravel colonne pour présenter une solution de contexte anormal Laravel à tout le monde, j'espère qu'elle sera utile aux amis qui en ont besoin !

Récemment, le projet a rencontré une situation. Lorsque nous rencontrons un utilisateur qui n'a pas l'autorisation d'accéder à certaines informations, nous espérons demander une raison détaillée, par exemple, lors de l'accès à une ressource de l'équipe et à l'accès des non-membres. dessus, une invite sera donnée :

, et le nom codé de l'équipe et le bouton de participation doivent être affichés en même temps. Cependant, la logique de l'interface est d'afficher directement 您不是 [xxxxxx] 团队的成员,暂时无法查看,可589dbe80f52208edfac91e23a0ccf85e lorsqu'il n'y a pas d'autorisation : <.>

abort_if(!$user->isMember($resouce->team), 403, '您无权访问该资源');
abort Le résultat de la réponse obtenue est le suivant :

HTTP/1.0 403 Forbidden{
    "message": "您无权访问该资源"}

Il nous est impossible d'utiliser du HTML pour afficher la page d'invite du front-end pour les messages. Cela serait trop couplé et violerait le principe de. séparation front-end et back-end. Notre objectif est de renvoyer le format suivant pour résoudre le problème :

HTTP/1.0 403 Forbidden{
    "message": "您无权访问该资源",
    "team": {
        "id": "abxT8sioa0Ms",
        "name": "CoDesign****"
    }}

La transmission de données en transportant le contexte facilite la combinaison libre des étudiants front-end.

Démarrer la transformationBien sûr, ce n'est pas une question compliquée, il suffit de modifier l'original

pour le résoudre :

- 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);
+ }
abort_if Cela semble résoudre le problème, mais imaginez, si une exception est détectée dans la fermeture et que vous souhaitez quitter, le style d'écriture

ci-dessus sera plus difficile après tout,

ne fera que se terminer. . Dans le contexte récent, nous espérons toujours mettre fin à l'exécution de l'ensemble de l'application comme return puis effectuer une autre transformation. returnabort

Implémentation optimisée de Après avoir regardé le code source

, j'ai découvert que son premier paramètre prend en charge les instances

, et ce qui précède Le résultat de notre abort est son instance, il nous suffit donc de le changer comme ceci : SymfonyComponentHttpFoundationResponse

 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));
 }
return semble avoir implémenté des interruptions anormales, mais un nouveau problème est survenu si nécessaire. réutilisé, c'est embarrassant. Ce code apparaîtra à plusieurs reprises dans divers endroits où cette autorisation est jugée. Ce n'est pas ce que nous voulons.

Réutilisation logique

Afin de réaliser la réutilisation logique, j'ai examiné l'implémentation de

et j'ai découvert que la méthode

de la classe parent a également cette conception : AppExceptionsHandler

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 Nous pouvons donc extraire cette logique dans une classe d'exception indépendante et implémenter la méthode

:

render Nous créons d'abord une classe d'exception :

$ ./artisan make:exception NotTeamMemberException

L'implémentation Le code est le suivant :

<?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
        );
    }
}

De cette façon, notre logique devient :

if (!$user->isMember($resouce->team)) {
     throw new NotTeamMemberException($resouce->team, &#39;您无权访问该资源&#39;);
}

Bien sûr, il peut aussi être abrégé en :

\throw_if(!$user->isMember($resouce->team), NotTeamMemberException::class, $resouce->team, &#39;您无权访问该资源&#39;);

Le problème est finalement résolu avec une comparaison La solution parfaite. Si vous avez une meilleure solution, veuillez laisser un commentaire.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer