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

2022-08-30 07:33:35

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

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

这是设置的示例;

-- 路线.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);
    }

-- 页面控制器.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()


答案 1

我相信执行此操作的正确方法(在 Laravel 5.x 中)是将自定义字段添加到属性属性中。

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

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

因此,您将按如下方式实现它;

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

然后,您可以通过调用以下命令来检索该属性:

\Request::get('myAttribute');

或者从 laravel 5.5+ 中的请求对象

 $request->get('myAttribute');

答案 2

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

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

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

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

class PagesController 
{
    protected $page;

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

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


推荐