Ich führe eine Berechtigungsprüfung für einen Benutzer durch, um festzustellen, ob er eine Seite anzeigen kann oder nicht. Dazu muss die Anforderung zuerst über eine Middleware weitergeleitet werden.
Das Problem, das ich habe, ist, dass ich dieselbe Datenbankabfrage in der Middleware und im Controller dupliziere, bevor ich die Daten an die Ansicht selbst zurückgebe.
Hier ist ein Beispiel für das Setup.
- route.php
Route::get('pages/{id}', [
'as' => 'pages',
'middleware' => 'pageUser'
'uses' => 'PagesController@view'
]);
- PageUserMiddleware.php (Klasse 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]);
}
Wie Sie sehen können, Page::with('users')->where('id', $id)->first()
wird dies sowohl in der Middleware als auch im Controller wiederholt. Ich muss die Daten von einem zum anderen weitergeben, um sie nicht zu duplizieren.
Antworten:
Ich glaube, der richtige Weg, dies zu tun (in Laravel 5.x), besteht darin, Ihre benutzerdefinierten Felder zur Attributeigenschaft hinzuzufügen.
Aus den Quellcode-Kommentaren können wir ersehen, dass Attribute für benutzerdefinierte Parameter verwendet werden:
Sie würden dies also wie folgt implementieren:
Sie können das Attribut dann abrufen, indem Sie Folgendes aufrufen:
Oder vom Anforderungsobjekt in Laravel 5.5+
quelle
$request->request->add(['myAttribute' => 'myValue']);
, um die Kurzschrift Magic Getter verwenden zu können$request->myAttribute
Anstelle von benutzerdefinierten Anforderungsparametern können Sie dem Kontrollinversionsmuster folgen und die Abhängigkeitsinjektion verwenden.
Registrieren Sie in Ihrer Middleware Ihre
Page
Instanz:app()->instance(Page::class, $page);
Erklären Sie dann, dass Ihr Controller eine
Page
Instanz benötigt:Laravel löst die Abhängigkeit automatisch auf und instanziiert Ihren Controller mit der
Page
Instanz, die Sie in Ihrer Middleware gebunden haben.quelle
In laravel> = 5 können Sie
$request->merge
in der Middleware Folgendes verwenden :Und in der Steuerung:
quelle
Request::instance()
statisch zugreifen , anstatt zu verwenden$request
?Laravel 5.7
und
quelle
Wie in einem der obigen Kommentare für Laravel 5.3.x erwähnt
Funktioniert nicht Das Einstellen der Variablen in der Middleware funktioniert jedoch
Ich könnte die Daten damit in meinem Controller abrufen
quelle
Ich bin sicher, wenn es möglich wäre, Daten von einer Middleware an einen Controller zu übergeben, wäre dies in der Laravel-Dokumentation enthalten.
Schauen Sie sich dies und das an , es könnte helfen.
Kurz gesagt, Sie können Ihre Daten auf das Anforderungsobjekt zurücksetzen, das an die Middleware übergeben wird. Das macht auch die Laravel-Authentifizierungsfassade.
In Ihrer Middleware können Sie also Folgendes haben:
quelle
Es ist sehr einfach:
Hier ist Middleware-Code:
und hier ist Controller-Code:
quelle
Wenn Ihre Website CMS-Seiten enthält, die aus der Datenbank abgerufen werden und deren Titel im Kopf- und Fußzeilenblock auf allen Seiten der Laravel-Anwendung angezeigt werden sollen, verwenden Sie Middleware. Schreiben Sie den folgenden Code in Ihre Middleware:
Gehen Sie dann zu Ihrer header.blade.php und footer.blade.php und schreiben Sie den folgenden Code, um Links von cms-Seiten hinzuzufügen:
Vielen Dank an alle und viel Spaß mit dem Code :)
quelle
Ich spreche kein Englisch, also ... Entschuldigung für mögliche Fehler.
Sie können hierfür die IoC-Bindung verwenden. In Ihrer Middleware können Sie dies tun, um die $ page-Instanz zu binden:
Danach rufen Sie in Ihrem Controller diese Instanz auf:
Die App :: -Instanz instanziiert die Klasse nicht erneut, sondern gibt die zuvor verbindliche Instanz zurück.
quelle
Ich konnte dem Request-Objekt Werte hinzufügen mit:
und holen Sie sie zu einem späteren Zeitpunkt zurück mit:
Dies ist möglich , weil laravels Antrag erstreckt symfonys anfordern , die das Attribut „ Attribute $ “ vom Typ ParameterBag , die zu halten , sollten benutzerdefinierte Parameter .
Ich denke, dies sollte eine bewährte Methode sein, um Daten an nachfolgende Middleware, Controller oder einen anderen Ort zu übergeben, an dem auf das Request-Objekt zugegriffen werden kann.
Getestet mit Laravel 5.6 , aber wahrscheinlich auch mit anderen Versionen.
quelle
$request
ist das Array, so dass wir dem Array einfach Wert und Schlüssel hinzufügen und den$request
mit diesem Schlüssel im Controller abrufen können.$request['id'] = $id;
quelle