Php Laravel中间件将变量返回控制器

Php Laravel中间件将变量返回控制器,php,laravel,laravel-5,laravel-middleware,Php,Laravel,Laravel 5,Laravel Middleware,我正在对用户执行权限检查,以确定他们是否可以查看页面。这包括首先通过一些中间件传递请求 我遇到的问题是,在将数据返回到视图本身之前,我在中间件和控制器中复制了相同的数据库查询 下面是一个设置示例 --routes.php Route::get('pages/{id}', [ 'as' => 'pages', 'middleware' => 'pageUser' 'uses' => 'PagesController@view' ]); --PageUserMi

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

我遇到的问题是,在将数据返回到视图本身之前,我在中间件和控制器中复制了相同的数据库查询

下面是一个设置示例

--routes.php

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

--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文档中

看一看,也许会有帮助

简而言之,您可以在传递给中间件的请求对象上携带数据。Laravel认证门面也可以做到这一点

因此,在中间件中,您可以:

$request->myAttribute = "myValue";

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

看一看,也许会有帮助

简而言之,您可以在传递给中间件的请求对象上携带数据。Laravel认证门面也可以做到这一点

因此,在中间件中,您可以:

$request->myAttribute = "myValue";

我认为正确的方法(在Laravel5.x中)是将自定义字段添加到attributes属性中

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

 /**
 * Custom parameters.
 *
 * @var \Symfony\Component\HttpFoundation\ParameterBag
 *
 * @api
 */
public $attributes;
因此,您将按如下方式实现此功能:

$request->attributes->add(['myAttribute' => 'myValue']);
然后,可以通过调用以下命令检索属性:

\Request::get('myAttribute');
或来自laravel 5.5中的请求对象+

 $request->get('myAttribute');

我认为正确的方法(在Laravel5.x中)是将自定义字段添加到attributes属性中

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

 /**
 * Custom parameters.
 *
 * @var \Symfony\Component\HttpFoundation\ParameterBag
 *
 * @api
 */
public $attributes;
因此,您将按如下方式实现此功能:

$request->attributes->add(['myAttribute' => 'myValue']);
然后,可以通过调用以下命令检索属性:

\Request::get('myAttribute');
或来自laravel 5.5中的请求对象+

 $request->get('myAttribute');

我不会说英语,所以。。。对不起,可能有错误

您可以为此使用IoC绑定。在中间件中,您可以为绑定$page实例执行以下操作:

\App::instance('mi_page_var', $page);
$page = \App::make('mi_page_var');
class PagesController 
{
    protected $page;

    function __construct(Page $page) 
    {
        $this->page = $page;
    }
}
之后,在控制器中调用该实例:

\App::instance('mi_page_var', $page);
$page = \App::make('mi_page_var');
class PagesController 
{
    protected $page;

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

App::instance不会重新实例化该类,而是返回实例先前的绑定。

我不会说英语,所以。。。对不起,可能有错误

您可以为此使用IoC绑定。在中间件中,您可以为绑定$page实例执行以下操作:

\App::instance('mi_page_var', $page);
$page = \App::make('mi_page_var');
class PagesController 
{
    protected $page;

    function __construct(Page $page) 
    {
        $this->page = $page;
    }
}
之后,在控制器中调用该实例:

\App::instance('mi_page_var', $page);
$page = \App::make('mi_page_var');
class PagesController 
{
    protected $page;

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

App::instance不会重新实例化该类,而是返回实例之前的绑定。

您可以遵循控制模式的反转并使用依赖项注入,而不是自定义请求参数

在中间件中,注册
页面
实例:

\App::instance('mi_page_var', $page);
$page = \App::make('mi_page_var');
class PagesController 
{
    protected $page;

    function __construct(Page $page) 
    {
        $this->page = $page;
    }
}
app()->实例(Page::class$Page)

然后声明控制器需要一个
页面
实例:

\App::instance('mi_page_var', $page);
$page = \App::make('mi_page_var');
class PagesController 
{
    protected $page;

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

Laravel将自动解析依赖关系,并使用绑定在中间件中的
页面
实例实例化控制器。

您可以遵循控制反转模式并使用依赖关系注入,而不是自定义请求参数

在中间件中,注册
页面
实例:

\App::instance('mi_page_var', $page);
$page = \App::make('mi_page_var');
class PagesController 
{
    protected $page;

    function __construct(Page $page) 
    {
        $this->page = $page;
    }
}
app()->实例(Page::class$Page)

然后声明控制器需要一个
页面
实例:

\App::instance('mi_page_var', $page);
$page = \App::make('mi_page_var');
class PagesController 
{
    protected $page;

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

Laravel将自动解决依赖关系,并使用您绑定在中间件中的
页面
实例实例化控制器。

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

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

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

    return $next($request);
}
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);

}
在控制器中:

public function index(Request $request)
{

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

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

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

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

    return $next($request);
}
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);

}
在控制器中:

public function index(Request $request)
{

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

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

$request->attributes->add(['key => 'value'] ); 
不起作用。但是在中间件中这样设置变量是可行的

$request->attributes->set('key', 'value');
我可以在我的控制器中使用它获取数据

$request->get('key');

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

$request->attributes->add(['key => 'value'] ); 
不起作用。但是在中间件中这样设置变量是可行的

$request->attributes->set('key', 'value');
我可以在我的控制器中使用它获取数据

$request->get('key');

$request
是数组,因此我们可以向数组添加值和键,并在控制器中使用此键获取
$request


$request['id']=$id
$request
是数组,因此我们可以向数组添加值和键,并在控制器中使用此键获取
$request


$request['id']=$id

我可以通过以下方式向请求对象添加值:

$request->attributes->set('key', 'value');
并在以后的某个时间使用以下工具将其取回:

$request->attributes->get('key');
这是可能的,因为扩展具有要保留的类型的属性“”

我认为这应该是将数据传递到后续中间件、控制器或任何其他可以访问请求对象的地方的最佳实践


使用Laravel 5.6进行了测试,但可能也使用了其他版本。

我能够通过以下方式向请求对象添加值:

$request->attributes->set('key', 'value');
并在以后的某个时间使用以下工具将其取回:

$request->attributes->get('key');
这是可能的,因为扩展具有要保留的类型的属性“”

我认为这应该是将数据传递到后续中间件、控制器或任何其他可以访问请求对象的地方的最佳实践

使用Laravel 5.6进行测试,但也可能使用其他版本。

非常简单:

以下是中间件代码:

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

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

    return $next($request);
}
以下是控制器代码:

$request->customVar;
这很简单:

以下是中间件代码:

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

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

    return $next($request);
}
这是控制器