Появилась нужда из посредника (middleware) при НЕ прохождении проверки редиректить с определёнными параметрами в контроллер. Никогда с IoC ещё не сталкивался и решил его использовать:
middleware:
public function handle($request, Closure $next)
{
$nowUserIp = $request->ip();
$findIps = UserIp::where('ip', $nowUserIp)->get();
if ($findIps->isEmpty()) {
$newUserIp = new UserIp();
$newUserIp->ip = $nowUserIp;
auth()->user()->UserIp()->save($newUserIp);
}
foreach ($findIps as $findIp) {
$hoursDiff = Carbon::now()->diffInHours($findIp->created_at, true);
if ($findIp->user_id != auth()->user()->id && $hoursDiff < 24) {
return redirect()->route('ip-ban');
}
}
return $next($request);
}
controller (куда в случае пойдёт /redirect. Сейчас с повторением кода, IoC не получается. Нужно передать из middleware $findIps = UserIp::where...
):
public function index(Request $request)
{
$nowUserIp = $request->ip();
$findIps = UserIp::where('ip', $nowUserIp)->get();
foreach ($findIps as $findIp) {
$hoursDiff = Carbon::now()->diffInHours($findIp->created_at, true);
if ($findIp->user_id != auth()->user()->id && $hoursDiff < 24) {
return 'Access Denied! Your ip is banned: ' . $findIp->ip;
}
}
return redirect('/');
}
Ничего не происходит, что я делаю не так? Пробовал способ из этого вопроса https://stackoverflow.com/questions/30212390/laravel-middleware-return-variable-to-controller/33297725#33297725 (Ответ crishoj) Ничего не выходит...
Варианты:
RedirectResponse
Если передавать данные для роута который в url, то там нельзя передавать сложные данные, например, экземпляр модели или коллекцию.
К счастью, вместе с редиректом можно передать данные в сессию Flash Data(данные хранятся только для следующего запроса):
return redirect()->route('ip-ban')->with(['data' => $data] );
Получить можно так:
session('data');
Конечно, это работает для всех видов редиректов (через экземпляр RedirectResponse ), это тоже будет работать:
return redirect()->action(
'TestController@testAction',
['data' => 123] // данные роута
)->with(['data' => $users]); // данные в сессию
Документация.
В Middleware можно вызвать action нужного контроллера передав ему нужные данные.
Код тестировался с передачей коллекции Eloquent, значит скорее всего можно передавать что угодно.
Работал следующий код:
routes/web.php
Route::middleware('redirect')->group(function () {
Route::get('/test', 'TestController@testAction');
});
Route::get('/test2', 'TestController@testAction2');
Middleware "redirect" (упустил код добавления в Kernel.php, не знаете как добавлять - смотрите документацию)
public function handle($request, Closure $next)
{
$users = \App\User::all();
$controller = app()->make(\App\Http\Controllers\TestController::class);
// передается массив параметров, `$users` попадет в первый параметр `$param`
$controller->callAction('testAction2', [$users]);
}
Контроллер TestController:
namespace App\Http\Controllers;
class TestController extends Controller
{
public function testAction()
{
return 'этот action не должен сработать';
}
public function testAction2($param)
{
// вывелась коллекция пользователей
dd($param);
}
}
На самом работает и без контейнера зависимостей, можно просто:
$con = new \App\Http\Controllers\TestController;
$con->callAction('testAction2', [$users]);
Пишите какие еще способы знаете.
В документации и в исходниках instance
примаент первый параметр как строку: https://github.com/laravel/framework/blob/5.7/src/Illuminate/Container/Container.php#L391
Попробуйте этот вариант:
// свзязывает экземпляр с контейнером
app()->instance('userIp', $findIp);
Дальше в контейнере просто получите этот экземпляр. Вместо того чтобы писать
$this->findIp = app()->make('userIp');
Можно
$this->findIp = resolve('userIp');
Почему там в ответе используется "route model binding" если маршрут тут не причем я не знаю, по идее оно не должно работать.
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
*Возникшие ошибки: Error parsing XML feed: Not allowed value "THB" for the attribute "id": XML tag "currency"Столбец 37 Строка 9
Мне необходимо начинать загрузку видео с сервера на странице после того как пользователь доскролит до этого местаВидео на страницу вставляются...