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');