webentwicklung-frage-antwort-db.com.de

Laravel Middleware-Rückgabevariable an Controller

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 geleitet werden.

Das Problem, das ich habe, ist, dass ich die gleiche Datenbankabfrage in der Middleware und im Controller dupliziere, bevor ich die Daten an die Ansicht selbst zurückgebe.

Hier ist ein Beispiel für die Einrichtung;

- routes.php

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

- 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, wird die Page::with('users')->where('id', $id)->first() sowohl in der Middleware als auch im Controller wiederholt. Ich muss die Daten von einem zum anderen weitergeben, um sie nicht zu duplizieren.

65
Alex

Ich glaube, dass der richtige Weg, dies zu tun (in Laravel 5.x)), darin besteht, Ihre benutzerdefinierten Felder der Eigenschaft attributes hinzuzufügen.

Aus den Quellcodekommentaren können wir ersehen, dass Attribute für benutzerdefinierte Parameter verwendet werden:

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

Sie würden dies also wie folgt implementieren:

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

Sie können das Attribut dann abrufen, indem Sie Folgendes aufrufen:

\Request::get('myAttribute');

Oder vom Anfrageobjekt in laravel 5.5+

 $request->get('myAttribute');
108
Gaz_Edge

Anstelle von benutzerdefinierten Anforderungsparametern können Sie dem Inversion-of-Control-Muster folgen und die Abhängigkeitsinjektion verwenden.

Registrieren Sie in Ihrer Middleware Ihre Page -Instanz:

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

Deklarieren Sie dann, dass Ihr Controller eine Page -Instanz benötigt:

class PagesController 
{
    protected $page;

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

Laravel löst die Abhängigkeit automatisch auf und instanziiert Ihren Controller mit der Instanz Page, die Sie in Ihre Middleware eingebunden haben.

20
crishoj

In laravel> = 5 können Sie $request->merge in der Middleware:

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

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

    return $next($request);
}

Und im Controller:

public function index(Request $request)
{

    $myVar = $request->instance()->query('myVar');
    ...
}
15
Vinicius

Ich bin mir sicher, wenn es möglich wäre, Daten von einer Middleware an einen Controller zu übertragen, finden Sie diese in der Laravel Dokumentation.

Schauen Sie sich this und this an, es könnte helfen.

Kurz gesagt, Sie können Ihre Daten auf das Anforderungsobjekt übertragen, das an die Middleware übergeben wird. Die Laravel Authentifizierungsfassade macht das auch.

In Ihrer Middleware können Sie also Folgendes haben:

$request->myAttribute = "myValue";
6
Noman Ur Rehman

Wie in einem der obigen Kommentare für laravel 5.3.x erwähnt

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

Funktioniert nicht Das Setzen der Variablen in der Middleware funktioniert jedoch

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

Ich könnte die Daten mit diesem in meinem Steuerpult holen

$request->get('key');
5
Tariq Khan

Laravel 5.7

// in Middleware register instance
app()->instance('myObj', $myObj);

und

// to get in controller just use the resolve helper
$myObj = resolve('myObj');

Es ist sehr einfach:

Hier ist der Middleware-Code:

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

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

    return $next($request);
}

und hier ist der Controller-Code:

$request->customVar;
3
Ashfaq Muhammad

$ request ist das Array, sodass wir nur Wert und Schlüssel zum Array hinzufügen und die $ request mit diesem Schlüssel im Controller abrufen können.

$ request ['id'] = $ id;

2
Durgesh Pandey

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 Anwendung laravel=) angezeigt werden sollen, verwenden Sie 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);

}

Gehen Sie dann zu header.blade.php und footer.blade.php und schreiben Sie den folgenden Code, um Links von CMS-Seiten hinzuzufügen:

<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>

Vielen Dank an alle und viel Spaß mit dem Code :)

2
Kamlesh

Ich konnte dem Request-Objekt Werte hinzufügen mit:

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

und holen sie sich zu einem späteren Zeitpunkt zurück mit:

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

Dies ist möglich, weil laravels Request erweitert symfonys Request das Attribut " $ attributes " vom Typ ParameterBag hat soll benutzerdefinierte Parameter halten.

Ich denke, dies sollte Best Practice sein, um Daten an nachfolgende Middleware, Controller oder an jeden anderen Ort zu übertragen, an dem es möglich ist, auf das Request-Objekt zuzugreifen.

Getestet mit Laravel 5.6 , aber wahrscheinlich auch mit anderen Versionen.

1
suud

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 zum Binden der $ page-Instanz tun:

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

Danach rufen Sie in Ihrem Controller diese Instanz auf:

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

Die App :: -Instanz instanziiert die Klasse nicht erneut, sondern gibt stattdessen die Instanz zurück, die zuvor gebunden war.

1
Carlos Porter