Laravel Middleware retour variable au contrôleur

j'effectue un contrôle de permissions sur un utilisateur pour déterminer s'il peut voir une page ou non. Cela implique de passer d'abord la requête par un middleware.

le problème que j'ai est que je duplique la même requête de base de données dans le middleware et dans le contrôleur avant de retourner les données à la vue elle-même.

voici un exemple de configuration;

-- routes.php

Route::get('pages/{id}', [
   'as' => 'pages',
   'middleware' => 'pageUser'
   'uses' => 'PagesController@view'
]);

-- PageUserMiddleware.php (class PageUserMiddleware)

public function handle($request, Closure $next)
    {
        //get the page
        $pageId = $request->route('id');
        //find the page with users
        $page = Page::with('users')->where('id', $pageId)->first();
        //check if the logged in user exists for the page
        if(!$page->users()->wherePivot('user_id', Auth::user()->id)->exists()) {
            //redirect them if they don't exist
            return redirect()->route('redirectRoute');
        }
        return $next($request);
    }

-- PagesController.php

public function view($id)
{
    $page = Page::with('users')->where('id', $id)->first();
    return view('pages.view', ['page' => $page]);
}

comme vous pouvez le voir, le Page::with('users')->where('id', $id)->first() est répété dans le middleware et le contrôleur. Je dois passer les données de l'un à l'autre pour ne pas les dupliquer.

56
demandé sur ROMANIA_engineer 2015-05-13 13:38:24

9 réponses

je crois que la bonne façon de le faire (dans Laravel 5.x) est d'ajouter vos champs personnalisés à la propriété attributs.

D'après les commentaires du code source, nous pouvons voir que les attributs sont utilisés pour les paramètres personnalisés:

 /**
 * Custom parameters.
 *
 * @var \Symfony\Component\HttpFoundation\ParameterBag
 *
 * @api
 */
public $attributes;

pour que vous mettiez en œuvre ceci comme suit;

$request->attributes->add(['myAttribute' => 'myValue']);

vous pouvez alors récupérer l'attribut en appelant:

\Request::get('myAttribute');
76
répondu Gaz_Edge 2017-10-02 05:42:28

dans laravel >= 5 vous pouvez utiliser $request->merge dans le middleware:

public function handle($request, Closure $next)
{

    $request->merge(array("myVar" => "1234"));

    return $next($request);
}

et dans le contrôleur:

public function index(Request $request)
{

    $myVar = Request::instance()->query('myVar');
    ...
}
13
répondu Vinicius 2015-11-07 13:50:49

au lieu des paramètres de requête personnalisés, vous pouvez suivre le modèle d'inversion de contrôle et utiliser l'injection de dépendances.

dans votre middleware, enregistrez votre Page instance:

app()->instance(Page::class, $page);

alors déclarez que votre contrôleur a besoin d'une instance Page :

class PagesController 
{
    protected $page;

    function __construct(Page $page) 
    {
        $this->page = $page;
    }
}

Laravel résoudra automatiquement la dépendance et instanciera votre contrôleur avec le Page exemple que vous avez lié dans votre middleware.

11
répondu crishoj 2015-10-23 08:15:21

je suis sûr que s'il était possible de transmettre des données d'un middleware à un contrôleur, ce serait dans la documentation de Laravel.

regarder ce et ce , ça pourrait aider.

en bref, vous pouvez récupérer vos données sur l'objet request qui est passé dans le middleware. La façade d'authentification Laravel le fait aussi.

donc, dans votre middleware, vous pouvez ont:

$request->myAttribute = "myValue";
6
répondu Noman Ur Rehman 2017-05-23 12:26:22

, Comme mentionné dans l'un des commentaires ci-dessus pour laravel 5.3.x

$request->attributes->add(['key => 'value'] ); 

ne marche pas. Mais définir la variable comme ceci dans le middleware fonctionne

$request->attributes->set('key', 'value');

je pourrais récupérer les données en utilisant ceci dans mon contrôleur

$request->get('key');
3
répondu Tariq Khan 2017-09-27 15:30:11

$request est le tableau de sorte que nous pouvons juste ajouter de la valeur et de la clé au tableau et obtenir la requête $avec cette clé dans le contrôleur.

$ request ['id'] = $id;

2
répondu Durgesh Pandey 2017-11-15 10:54:24

c'est très simple:

voici middleware code:

public function handle($request, Closure $next)
{

    $request->merge(array("customVar" => "abcde"));

    return $next($request);
}

et voici le code du contrôleur:

$request->customVar;
2
répondu Ashfaq Muhammad 2018-08-07 07:56:04

je ne parle pas anglais, donc... désolé pour les éventuelles erreurs.

vous pouvez utiliser la reliure du CIO pour cela. Dans votre middleware, vous pouvez faire ceci pour lier $page instance:

\App::instance('mi_page_var', $page);

après, dans votre controller vous appelez cette instance:

$page = \App::make('mi_page_var');

de L'App::instance de ne pas re-instance de la classe, au lieu de retourner l'instance previusly de liaison.

1
répondu Carlos Porter 2015-08-18 10:04:51

j'ai pu ajouter des valeurs à la requête-objet avec:

$request->attributes->set('key', 'value');

et les faire revenir à un point plus tard:

$request->attributes->get('key');

cela est possible parce que demande laravels étend demande symfonys qui a l'attribut " $attributs de type ParameterBag qui est destiné à tenir paramètres personnalisés .

je pense que ce devrait être la meilleure pratique pour transmettre des données à des middlewares ultérieurs, contrôleurs ou tout autre endroit où il est possible d'accéder à la requête-objet.

Testé avec Laravel 5.6 , mais probablement aussi en travaillant avec d'autres versions.

0
répondu suud 2018-07-06 10:57:08