Returns the Laravel variable to the controller

I am performing a user rights check to determine if they can view the page or not. This includes transmitting the request through some middleware.

The problem is that I duplicate the same database query in the middleware and in the controller before returning the data to the view itself.

Here is an example setup;

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

As you can see, Page::with('users')->where('id', $id)->first() repeated both in the middleware and in the controller. I need to transfer data from one to another so as not to duplicate.

+63
php laravel laravel-5 laravel-middleware
May 13 '15 at 10:38
source share
11 answers

I believe that the correct way to do this (in Laravel 5.x) is to add your custom fields to the attribute property.

From the source code comments, we see that the attributes are used for custom parameters:

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

So you would implement it as follows;

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

Then you can get the attribute by calling:

 \Request::get('myAttribute'); 

Or from a request object in laravel 5. 5+

  $request->get('myAttribute'); 
+96
Jul 16 '15 at 12:22
source share

Instead of custom query parameters, you can follow the control inversion pattern and use dependency injection.

In your middleware, register an instance of Page :

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

Then declare that your controller needs an instance of Page :

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

Laravel will automatically resolve the dependency and create an instance of your controller with the Page instance that you linked in your middleware.

+17
Oct 23 '15 at 8:15
source share

In laravel> = 5, you can use $request->merge in middleware:

 public function handle($request, Closure $next) { $request->merge(array("myVar" => "1234")); return $next($request); } 

And in the controller:

 public function index(Request $request) { $myVar = $request->instance()->query('myVar'); ... } 
+14
Nov 07 '15 at 13:50
source share

I am sure that if it were possible to transfer data from middleware to the controller, that would be in the Laravel documentation.

Look this one and this one , it can help.

In short, you can copy your data to a request object that is passed to the middleware. The Laravel authentication facade does this too.

So, in your middleware, you can:

 $request->myAttribute = "myValue"; 
+6
May 13 '15 at 12:33
source share

As mentioned in one of the comments above for laravel 5.3.x

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

Does not work. But setting such a variable in middleware

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

I could extract data using this in my controller

 $request->get('key'); 
+4
Sep 27 '17 at 15:30
source share

Laravel 5.7

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

as well as

 // to get in controller just use the resolve helper $myObj = resolve('myObj'); 
+4
October 12 '18 at 19:29
source share

It is very simple:

Here is the middleware code:

 public function handle($request, Closure $next) { $request->merge(array("customVar" => "abcde")); return $next($request); } 

and here is the controller code:

 $request->customVar; 
+3
Aug 07 '18 at 7:56
source share

$ request is an array, so we can just add the value and key to the array and get $ request with that key in the controller.

$ request ['id'] = $ id;

+2
Nov 15 '17 at 10:54 on
source share

If your site has cms pages that are retrieved from the database and you want to display their headers in the header and footer blocks on all pages of the laravel application, use middleware. Write the code below in your 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); } 

Then go to your header.blade.php and footer.blade.php and write the code below to add links to cms pages:

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

Thanks a lot to everyone and enjoy the code :)

+2
Jan 19 '19 at 15:18
source share

I don’t speak English, so ... sorry for the possible mistakes.

You can use the IoC binding for this. In your middleware, you can do this to bind an instance of $ page:

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

After that, in the controller, you call this instance:

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

App :: instance does not repeat the instance of the class; instead, it returns the instance preceding the binding.

+1
Aug 18 '15 at 10:03
source share

I was able to add values ​​to the request object with:

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

and return them later with:

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

This is possible because the laravels Request extends a symfonys request that has a " $ attribute " of type ParameterBag to store user parameters .

I think that this should be the best practice for transferring data to subsequent middleware, controllers, or any other place where it is possible to access the request object.

Tested with Laravel 5.6 , but probably also works with other versions.

+1
Jul 6 '18 at 10:57
source share



All Articles