Laravel Middleware return variable to controller

2019-01-13 05:15发布

I am carrying out a permissions check on a user to determine whether they can view a page or not. This involves passing the request through some middleware first.

The problem I have is I am duplicating the same database query in the middleware and in the controller before returning the data to the view itself.

Here is an example of the 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, the Page::with('users')->where('id', $id)->first() is repeated in both the middleware and controller. I need to pass the data through from one to the other so an not to duplicate.

10条回答
Melony?
2楼-- · 2019-01-13 05:58

I am sure if it was possible to pass data from a middleware to a controller then it would be in the Laravel documentation.

Have a look at this and this, it might help.

In short, you can piggy back your data on the request object which is being passed to the middleware. The Laravel authentication facade does that too.

So, in your middleware, you can have:

$request->myAttribute = "myValue";
查看更多
太酷不给撩
3楼-- · 2019-01-13 06:02

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

From the source code comments, we can see attributes is used for custom parameters:

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

So you would implement this as follows;

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

You can then retrieved the attribute by calling:

\Request::get('myAttribute');
查看更多
啃猪蹄的小仙女
4楼-- · 2019-01-13 06:06

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

$request['id'] = $id;

查看更多
叛逆
5楼-- · 2019-01-13 06:07

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

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

Doesn't work. But setting the variable like this in the middleware works

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

I could fetch the data using this in my controller

$request->get('key');
查看更多
登录 后发表回答