Я провожу проверку разрешений для пользователя, чтобы определить, могут ли они просматривать страницу или нет. Это включает в себя передачу запроса через некоторое промежуточное программное обеспечение.
У меня проблема в том, что я дублирую один и тот же запрос к базе данных в промежуточном программном обеспечении и в контроллере перед возвратом данных в само представление.
Вот пример настройки;
- 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) - добавить свои настраиваемые поля в свойство 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');
источник
$request->request->add(['myAttribute' => 'myValue']);
чтобы иметь возможность использовать сокращение magic getter$request->myAttribute
Вместо настраиваемых параметров запроса вы можете следовать шаблону инверсии управления и использовать внедрение зависимостей.
В промежуточном программном обеспечении зарегистрируйте свой
Page
экземпляр:app()->instance(Page::class, $page);
Затем объявите, что вашему контроллеру нужен
Page
экземпляр:class PagesController { protected $page; function __construct(Page $page) { $this->page = $page; } }
Laravel автоматически разрешит зависимость и создаст экземпляр вашего контроллера с
Page
экземпляром, который вы связали в своем промежуточном программном обеспечении.источник
В 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'); ... }
источник
Request::instance()
нужен статический доступ , а не использование$request
?Laravel 5.7
// in Middleware register instance app()->instance('myObj', $myObj);
а также
// to get in controller just use the resolve helper $myObj = resolve('myObj');
источник
Как упоминалось в одном из комментариев выше для laravel 5.3.x
$request->attributes->add(['key => 'value'] );
Не работает. Но установка такой переменной в промежуточном программном обеспечении работает
$request->attributes->set('key', 'value');
Я мог бы получить данные, используя это в своем контроллере
$request->get('key');
источник
Я уверен, что если бы можно было передавать данные из промежуточного программного обеспечения в контроллер, это было бы в документации Laravel.
Взгляните на это и на это , это может помочь.
Короче говоря, вы можете скопировать свои данные в объект запроса, который передается промежуточному программному обеспечению. Фасад аутентификации Laravel тоже делает это.
Итак, в вашем промежуточном программном обеспечении вы можете иметь:
$request->myAttribute = "myValue";
источник
Это очень просто:
Вот код промежуточного программного обеспечения:
public function handle($request, Closure $next) { $request->merge(array("customVar" => "abcde")); return $next($request); }
и вот код контроллера:
источник
Если на вашем веб-сайте есть cms-страницы, которые извлекаются из базы данных и хотят отображать их заголовки в блоке верхнего и нижнего колонтитула на всех страницах приложения laravel, используйте промежуточное ПО. Напишите ниже код в промежуточном программном обеспечении:
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); }
Затем перейдите к вашим header.blade.php и footer.blade.php и напишите ниже код для добавления ссылок на страницы cms:
<a href="{{ url('/') }}">Home</a> | @foreach ($cms_pages as $page) <a href="{{ url('page/show/'.$page->id) }}">{{ $page->title }}</a> | @endforeach <a href="{{ url('contactus') }}">Contact Us</a>
Большое спасибо всем и наслаждайтесь кодом :)
источник
Я не говорю по-английски, так что ... извините за возможные ошибки.
Для этого можно использовать привязку IoC. В вашем промежуточном программном обеспечении вы можете сделать это для привязки экземпляра $ page:
\App::instance('mi_page_var', $page);
После этого в вашем контроллере вы вызываете этот экземпляр:
$page = \App::make('mi_page_var');
App :: instance не повторно создает экземпляр класса, а возвращает предыдущую привязку экземпляра.
источник
Мне удалось добавить значения к объекту запроса с помощью:
$request->attributes->set('key', 'value');
и верните их позже с помощью:
$request->attributes->get('key');
Это возможно, потому что laravels Request расширяет Symfonys Request, который имеет атрибут « $ attributes » типа ParameterBag, который предназначен для хранения пользовательских параметров .
Я думаю, что это должна быть Лучшая практика для передачи данных в последующее промежуточное программное обеспечение, контроллеры или любое другое место, где можно получить доступ к объекту запроса.
Протестировано с Laravel 5.6 , но, вероятно, также работает с другими версиями.
источник
$request
- это массив, чтобы мы могли просто добавить значение и ключ к массиву и получить с$request
помощью этого ключа в контроллере.$request['id'] = $id;
источник