Я выполняю проверку прав доступа пользователя, чтобы определить, могут ли они просматривать страницу или нет. Это включает в себя передачу запроса через некоторое промежуточное программное обеспечение в первую очередь.
У меня проблема в том, что я дублирую один и тот же запрос к базе данных в промежуточном программном обеспечении и в контроллере, прежде чем вернуть данные в само представление.
Вот пример настройки;
— 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) — добавить свои настраиваемые поля в свойство attribute.
Из комментариев исходного кода мы видим, что атрибуты используются для пользовательских параметров:
/**
* 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');
...
}
Вместо пользовательских параметров запроса вы можете следовать шаблону инверсии управления и использовать внедрение зависимостей.
В промежуточном программном обеспечении зарегистрируйте свой Page
пример:
app()->instance(Page::class, $page);
Затем объявите, что ваш контроллер нуждается в Page
пример:
class PagesController
{
protected $page;
function __construct(Page $page)
{
$this->page = $page;
}
}
Laravel автоматически разрешит зависимость и создаст экземпляр вашего контроллера с помощью Page
экземпляр, который вы связали в своем промежуточном программном обеспечении.
Я уверен, что если бы можно было передавать данные из промежуточного программного обеспечения в контроллер, то это было бы в документации Laravel.
Посмотри на этот а также этот, это может помочь.
Короче говоря, вы можете добавить свои данные в объект запроса, который передается промежуточному программному обеспечению. Фасад аутентификации Laravel делает это тоже.
Итак, в вашем промежуточном программном обеспечении вы можете иметь:
$request->myAttribute = "myValue";
Как упомянуто в одном из комментариев выше для laravel 5.3.x
$request->attributes->add(['key => 'value'] );
Не работает Но установка такой переменной в промежуточном программном обеспечении работает
$request->attributes->set('key', 'value');
Я мог бы получить данные, используя это в моем контроллере
$request->get('key');
Это очень просто:
Вот код промежуточного программного обеспечения:
public function handle($request, Closure $next)
{
$request->merge(array("customVar" => "abcde"));
return $next($request);
}
и вот код контроллера:
$request->customVar;
// in Middleware register instance
app()->instance('myObj', $myObj);
а также
// to get in controller just use the resolve helper
$myObj = resolve('myObj');
$ request — это массив, так что мы можем просто добавить значение и ключ в массив и получить $ request с этим ключом в контроллере.
$ request [‘id’] = $ id;