J'effectue une vérification des autorisations sur un utilisateur pour déterminer s'il peut afficher une page ou non. Cela implique d'abord de passer la requête via 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 renvoyer les données à la vue elle-même.
Voici un exemple de la configuration;
- routes.php
Route::get('pages/{id}', [
'as' => 'pages',
'middleware' => 'pageUser'
'uses' => 'PagesController@view'
]);
- PageUserMiddleware.php (classe 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é à la fois dans le middleware et le contrôleur. J'ai besoin de transmettre les données de l'une à l'autre pour ne pas les dupliquer.
Réponses:
Je pense que la bonne façon de faire cela (dans Laravel 5.x) est d'ajouter vos champs personnalisés à la propriété attributes.
À partir des 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;
Vous implémenteriez donc ceci comme suit;
$request->attributes->add(['myAttribute' => 'myValue']);
Vous pouvez ensuite récupérer l'attribut en appelant:
\Request::get('myAttribute');
Ou à partir de l'objet de requête dans laravel 5.5+
$request->get('myAttribute');
la source
$request->request->add(['myAttribute' => 'myValue']);
pour pouvoir utiliser la sténographie du getter magique$request->myAttribute
Au lieu de paramètres de demande 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);
Déclarez ensuite que votre contrôleur a besoin d'une
Page
instance:class PagesController { protected $page; function __construct(Page $page) { $this->page = $page; } }
Laravel résoudra automatiquement la dépendance et instanciera votre contrôleur avec l'
Page
instance que vous avez liée dans votre middleware.la source
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'); ... }
la source
Request::instance()
manière statique plutôt que d'utiliser$request
?Laravel 5.7
// in Middleware register instance app()->instance('myObj', $myObj);
et
// to get in controller just use the resolve helper $myObj = resolve('myObj');
la source
Comme mentionné dans l'un des commentaires ci-dessus pour laravel 5.3.x
$request->attributes->add(['key => 'value'] );
Ça ne marche pas. Mais définir la variable comme celle-ci 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');
la source
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 Laravel.
Jetez un œil à ceci et cela , cela pourrait aider.
En bref, vous pouvez récupérer vos données sur l'objet de requête qui est transmis au middleware. La façade d'authentification Laravel le fait aussi.
Ainsi, dans votre middleware, vous pouvez avoir:
$request->myAttribute = "myValue";
la source
C'est très simple:
Voici le code middleware:
public function handle($request, Closure $next) { $request->merge(array("customVar" => "abcde")); return $next($request); }
et voici le code du contrôleur:
la source
Si votre site Web a des pages cms qui sont extraites de la base de données et que vous souhaitez afficher leurs titres dans le bloc d'en-tête et de pied de page sur toutes les pages de l'application laravel, utilisez un middleware. Écrivez ci-dessous le code dans votre middleware:
namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\DB; public function handle($request, Closure $next) { $data = DB::table('pages')->select('pages.id','pages.title')->where('pages.status', '1')->get(); \Illuminate\Support\Facades\View::share('cms_pages', $data); return $next($request); }
Ensuite, allez à votre header.blade.php et footer.blade.php et écrivez le code ci-dessous pour ajouter des liens de pages cms:
<a href="{{ url('/') }}">Home</a> | @foreach ($cms_pages as $page) <a href="{{ url('page/show/'.$page->id) }}">{{ $page->title }}</a> | @endforeach <a href="{{ url('contactus') }}">Contact Us</a>
Merci beaucoup à tous et profitez du code :)
la source
je ne parle pas anglais, donc ... désolé pour d'éventuelles erreurs.
Vous pouvez utiliser la liaison IoC pour cela. Dans votre middleware, vous pouvez le faire pour lier l'instance $ page:
\App::instance('mi_page_var', $page);
Ensuite, dans votre contrôleur, vous appelez cette instance:
$page = \App::make('mi_page_var');
L'instance App :: ne réinstalle pas la classe, mais retourne l'instance précédemment liée.
la source
J'ai pu ajouter des valeurs à l'objet Request avec:
$request->attributes->set('key', 'value');
et récupérez-les ultérieurement avec:
$request->attributes->get('key');
Ceci est possible parce que laravels Request étend symfonys Request qui a l'attribut " $ attributes " de type ParameterBag qui est destiné à contenir des paramètres personnalisés .
Je pense que cela devrait être la meilleure pratique pour transmettre des données à un middleware, à des contrôleurs ou à tout autre endroit où il est possible d'accéder à l'objet de requête.
Testé avec Laravel 5.6 , mais fonctionnant probablement aussi avec d'autres versions.
la source
$request
est le tableau afin que nous puissions simplement ajouter une valeur et une clé au tableau et obtenir le$request
avec cette clé dans le contrôleur.$request['id'] = $id;
la source