Laravel中间件返回variables给控制器

我正在对用户进行权限检查,以确定他们是否可以查看页面。 这涉及到通过一些中间件首先传递请求。

我有的问题是我在中间件和控制器中复制相同的数据库查询,然后将数据返回到视图本身。

这是一个设置的例子;

– routes.php

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

– PageUserMiddleware.php(类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]); } 

正如你所看到的,在中间件和控制器中, Page::with('users')->where('id', $id)->first()是重复的。 我需要将数据从一个传递到另一个,所以不要重复。

我相信正确的做法(在Laravel 5.x中)是将您的自定义字段添加到属性属性。

从源代码注释中,我们可以看到属性用于自定义参数:

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

所以你要实现这个如下;

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

然后您可以通过调用以下方法来检索属性

 \Request::get('myAttribute'); 

在laravel> = 5中,你可以在中间件中使用$request->merge

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

而在控制器中:

 public function index(Request $request) { $myVar = Request::instance()->query('myVar'); ... } 

我确信,如果有可能将数据从中间件传递到控制器,那么它将在Laravel文档中。

看看这个 ,这可能会有所帮助。

简而言之,您可以在传递给中间件的请求对象上捎带数据。 Laravelauthentication门面也是如此。

所以,在你的中间件中,你可以有:

 $request->myAttribute = "myValue"; 

而不是自定义的请求参数,你可以按照反转控制模式,并使用dependency injection。

在你的中间件中,注册你的Page实例:

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

然后声明你的控制器需要一个Page实例:

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

Laravel将自动parsing依赖关系,并使用您在中间件中绑定的Page实例来实例化您的控制器。

$ request是数组,因此我们可以只添加数值和键到数组中,并使用控制器中的这个键获取$ request。

$ request ['id'] = $ id;

我不会说英语,所以…抱歉可能的错误。

您可以使用IoC绑定。 在你的中间件中,你可以这样做绑定$ page实例:

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

之后,在你的控制器中你调用该实例:

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

App :: instance不重新实例类,而是返回事先绑定的实例。

正如上面对laravel 5.3.x的评论之一所述

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

不起作用。 但是在中间件中设置这样的variables是可行的

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

我可以在我的控制器中使用这个获取数据

 $request->get('key');