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

10 浏览
0 Comments

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

我正在对用户进行权限检查,以确定他们是否可以查看页面。这涉及首先通过一些中间件来传递请求。\n我遇到的问题是我在中间件和控制器中重复了相同的数据库查询,然后才将数据返回到视图本身。\n以下是设置的示例:\n-- routes.php\n

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

\n-- PageUserMiddleware.php(PageUserMiddleware类)\n

public function handle($request, Closure $next)
    {
        //获取页面
        $pageId = $request->route('id');
        //找到带有用户的页面
        $page = Page::with('users')->where('id', $pageId)->first();
        //检查登录的用户是否存在于页面中
        if(!$page->users()->wherePivot('user_id', Auth::user()->id)->exists()) {
            //如果不存在,将其重定向
            return redirect()->route('redirectRoute');
        }
        return $next($request);
    }

\n-- PagesController.php\n

public function view($id)
{
    $page = Page::with('users')->where('id', $id)->first();
    return view('pages.view', ['page' => $page]);
}

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

0
0 Comments

Laravel中的中间件(Middleware)是一种用于处理HTTP请求的机制,它可以在请求到达控制器之前或之后执行一些操作。在Laravel 5及以上的版本中,我们可以使用$request->merge方法在中间件中返回变量给控制器。

下面的代码演示了如何在中间件中使用$request->merge方法返回变量给控制器:

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

上述代码将在请求中添加一个名为myVar的变量,并将其值设为1234,然后将请求传递给下一个中间件或控制器。

在控制器中,我们可以通过$request->myVar来获取这个变量的值:

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

上述代码将获取到中间件中设置的myVar的值。

为什么会有人使用Request::instance()静态方法访问请求实例,而不是使用$request参数呢?这并不是一个好的解决方法,它可能导致意外的副作用。有关更多细节,请查看下面的回答:stackoverflow.com/a/73131117/8485567

我们可以通过在中间件中使用$request->merge方法返回变量给控制器。这种方式可以方便地在请求处理过程中传递数据,并且不会引起意外的副作用。相比于静态访问请求实例,使用$request参数更加安全可靠。

0
0 Comments

问题: Laravel中的中间件将变量返回给控制器的原因和解决方法

在Laravel中,我们可以使用依赖注入来避免使用自定义请求参数。以下是使用依赖注入的示例:

首先,在中间件中注册Page实例:

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

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

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

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

有人提出了一个很好的想法,他创建了一个服务提供者,并注册了一个服务容器。这样,当需要某些属性时,只需注入依赖项即可。更加简洁和透明。谢谢!

请问,你能详细解释一下你的方法吗?也就是说,如何使用依赖注入,以及它与中间件的关联。

当然!你可以创建一个自定义的服务容器类,将需要在中间件和控制器之间传递的数据作为内部属性保存在其中。如果你将该服务容器注册为单例(singleton)$this->app->singleton(...),那么每次注入它时都将得到同一个实例。因此,你可以首先在中间件中注入它(只需将其作为参数),然后将数据放入其中,并最后在控制器中引用它以访问这些数据。详见laravel.com/docs/5.4/container,祝你好运!

这是一个很好的答案...简洁! 🙂

备注:在__constructor中可能不起作用,因为中间件在控制器的构造函数之后加载。但你可以在控制器的任何动作中使用依赖注入。

在我的情况下,在构造函数中也可以正常工作。

0
0 Comments

Laravel Middleware return variable to controller

在Laravel中,如何将Middleware中的变量传递给Controller?这个问题的出现的原因是由于需要在Middleware中处理一些逻辑,并将处理结果传递给Controller进一步处理。下面是解决这个问题的方法:

在Laravel 5.x中,正确的方法是将自定义字段添加到attributes属性中。在源代码的注释中,我们可以看到attributes属性用于自定义参数。你可以按照以下方式实现:

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

你可以通过调用以下代码来获取这个属性:

\Request::get('myAttribute');

或在Laravel 5.5+中,可以从request对象中获取:

$request->get('myAttribute');

你可以将请求类添加到Controller方法的参数(IoC容器)中,或者调用静态类\Request来访问属性:

$myAttribute = \Request::get('myAttribute');

这种解决方法非常简洁!

如果在Middleware中使用`$request->attributes->add(['key' => 'value']);`无法生效,可以尝试使用`$request->attributes->set('key', 'value')`来设置属性,并使用`$request->get('key')`来获取数据。

对于Laravel 5.3.4版本,如果无法使其工作,请确保在调用Controller时Middleware也被调用。

如果想要添加一个对象而不仅仅是一个字符串值,可以像对待任何数组一样将对象添加到属性中。因为这只是一个数组。

在Laravel 5.4.23中,也可以使用`$request->request->add(['myAttribute' => 'myValue']);`来添加属性,并且可以使用魔术访问器的简写形式`$request->myAttribute`来访问。

但是,是否应该将这些属性添加到请求对象中是一个需要考虑的问题。请求对象应该只表示从浏览器获得的数据。

总结上述内容,我们可以通过将自定义字段添加到attributes属性中,然后使用`\Request::get('myAttribute')`或`$request->get('myAttribute')`来访问这些属性,从而在Laravel中实现将Middleware中的变量传递给Controller的功能。

0