Закодированные прямые слеши поддерживаются только для последнего сегмента.
Маршрутизация:
Содержание:
- Базовая маршрутизация
- Параметры маршрута
- Имена маршрута
- Сгруппированные маршруты
- Связь маршрута и модели
- Маршруты ошибки
- Ограничение числа запросов
- Имитация методов в формах
- Текущий адрес
Базовая маршрутизация:
Самый базовый маршрут для Ларавел принимает URL и возвращает функцию. Например, несколько слов в виде приветсвия:
Route::get('foo', function () {
return 'Привет мир!';
});
Стандартный файл маршрутизации:
Все маршруты определены в файлах, которые располагаются в специализированной директории routes. Эти файлы загружаются фреймворком автоматически.
Для большинства типовых приложений, пути определены в файле web.php. Получить доступ можно просто набрав указанный URL в браузере. Например, наберите http://your-app.test/user в браузере, чтобы получить доступ к указанному пути:
Route::get('/user', 'UserController@index');
Пути, которые определены в файле api.php сгруппированы RouteServiceProvider. Префикс применяется автоматически и его не нужно переопределять для каждого маршрута. Префикс и другие параметры можно изменить в классе RouteServiceProvider.
Доступные методы:
Маршрутизатор позволяет регистрировать пути, которые отвечают на любую HTTP команду:
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
Может возникнуть необходимость зарегистрировать маршрут, который отвечает на несколько команд одновременно. В этом случае, можно использовать метод match или any.
Route::match(['get', 'post'], '/', function () {
//
});
Route::any('/', function () {
//
});
CSRF Защита:
Любая HTML форма, которая отправляет даные методом POST, PUT или DELETE должна включать поле CSRF токена. В противном случае, запрос будет отклонён. Подробнее про CSRF защиту можно узнать в этом разделе. Пример CSRF поля:
<form method='POST' action='/profile'>
@csrf
...
</form>
Перенаправление:
Можно использовать метод Route::redirect, чтобы перенаправить с одного адреса на другой. Этот метод дасть возможность перенаправить запрос без использования контроллера или чего-либо ещё:
Route::redirect('/here', '/there');
По умолчанию Route::redirect возвращает код 302. Это значение можно переопределить 3-м параметром:
Route::redirect('/here', '/there', 301);
Чтобы получить 301 код по умолчанию, можно использовать метод Route::permanentRedirect:
Route::permanentRedirect('/here', '/there');
Ссылка на представление:
Если необходимо вернуть представление, можно использовать метод Route::view. Как и в случае с перенаправлением, токой метод позволит вернуть представление без контроллера и чего-либо ещё. Первым параметром нужно указать адрес, вторым параметром представление. Дополнительно можно указать набор данных третьим параметром.
Route::view('/welcome', 'welcome');
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
Параметры маршрута:
Требуемые параметры:
Иногда, требуется получить сегмент URL в качестве переменной. Для этого необходимо определить переменную в пути. Например, нужно определить ID пользователя:
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});
Можно определять любое количество параметров в маршруте:
Route::get('posts/{post}/comments/{comment}',
function ($postId, $commentId) {
//
});
Параметры берутся в скобочки {} и должны содержать буквы латинского алфавита, а не должны содержать тире - и других спецсимволов. Вместо того, чтобы использовать тире - используйте знак нижнего подчёркивания _. Параметры включаются в ответ вне зависимости от имени контроллера и чего-либо ещё.
Необязательные параметры:
Бывает ситуация, в которой параметр берётся по необходимости. В этом случае, можно поставить знак вопроса ? после параметра. Кроме того нужно убедиться в том, что у параметра есть значение по умолчанию.
Route::get('user/{name?}', function ($name = null) {
return $name;
});
Route::get('user/{name?}', function ($name = 'John') {
return $name;
});
Ограничение через регулярные выражения:
Вы можете ограничить формат параметров маршрута используя where метод. Берём заданный параметр, а регулярное выражение определяет какие ограничение у параметра могут быть:
Route::get('user/{name}', function ($name) {
//
})->where('name', '[A-Za-z]+');
Route::get('user/{id}', function ($id) {
//
})->where('id', '[0-9]+');
Route::get('user/{id}/{name}', function ($id, $name) {
//
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
Глобальные ограничения:
Если необходимо сделать так, чтобы параметры маршрута всегда были ограничены регулярными выражениями, то нужно использовать паттерн. Определить паттерн для метода boot можно в RouteServiceProvider:
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
Route::pattern('id', '[0-9]+');
parent::boot();
}
После того, как паттерн был единожды определён, он автоматически становится действительным для всех маршрутов:
Route::get('user/{id}', function ($id) {
// Only executed if {id} is numeric...
});
Закодированные прямы слеши:
Компонент маршрутизации позволяет работать со всеми символами, кроме прямых слешей /. Чтобы их спользовать, необходимо явно разрешить их использование через регулярные выражения в условии where.
Route::get('search/{search}', function ($search) {
return $search;
})->where('search', '.*');
Имя маршрута:
Имена маршрутов — это удобный способ работать с генерацией URL или редиректами. Вы можете указать имя маршрута через метод name в определении:
Route::get('user/profile', function () {
//
})->name('profile');
Также можно указывать имя для действия контроллера:
Route::get('user/profile', 'UserProfileController@show')
->name('profile');
Формирование URL для названных маршрутов:
После того, как вы назвали маршрут, можно сгенерировать URL путём обращения к имени через глобальную функцию route.
// Generating URLs...
$url = route('profile');
// Generating Redirects...
return redirect()->route('profile');
Если в названном маршруте определны парамтры, то можно передать значение через второй параметр функции. Такие параметры автоматически будут включены в URL в нужной позиции.
Route::get('user/{id}/profile', function ($id) {
//
})->name('profile');
$url = route('profile', ['id' => 1]);
Проверка текущего маршрута:
Если нужно определить, соответсвует текущий запрос имени маршрута, можно использовать метод named. Например, проверить запрос в промежуточном слое можно так:
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->route()->named('profile')) {
//
}
return $next($request);
}
Сгруппированные маршруты:
Сгрупированные маршруты позволяют использовать атрибуты для большого числа маршрутов, без необходимости определять каждый атрибут в каждом конкретном случае. Общие атрибуты указываются в формате массива в качестве первого параметра метода Route::group.
Кластеры дают возможность гибко управлять атрибутами. Можно объединить условия или промежуточный слой, в то время как простарство имён, имена и префиксы можно разделить. Разделители в прострастве имён и слеши автоматически добавляются в URL префиксы там, где необходимо.
Промежуточный слой:
Чтобы вписать промежуточный слой ко всей группе маршрутов, необходимо использовать метод middleware перед определением группы. Порядок выолнения соответсвует данным, указанным в массиве.
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// Uses first & second Middleware
});
Route::get('user/profile', function () {
// Uses first & second Middleware
});
});
Пространство имён:
Ещё один распространённый случай использования групп для маршрутов — это назначение простраства имён к группе контроллеров с помощью метода namespace.
Route::namespace('Admin')->group(function () {
// Controllers Within The "App\Http\Controllers\Admin" Namespace
});
По умолчанию, RouteServiceProvider включает файл маршрута с простаранством имён, что позволяет обращаться к контроллеру без детализации полного App\Http\Controllers пути. Поэтому, детализировать необходимо лишь оставшуюся часть:
Субдоменная маршрутизация:
Группирование может быть также использовано для субдоменных маршрутов. Параметры маршрута можно прописывать таким же образом, как и для URL-адреса. Для этого необходимо использовать метод domain перед определением группы.
Route::domain('{account}.myapp.com')->group(function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
Префиксы маршрутов:
Метод prefix используется для того, чтобы назначить префикс в группе для каждого конкретного URL. Например, все следующие маршруты имеют префикс admin:
Route::prefix('admin')->group(function () {
Route::get('users', function () {
// Matches The "/admin/users" URL
});
});
Префиксы имени маршрутов:
Метод name можно использовать для того, чтобы назначить префикс к каждому имени маршрута в данной группе. Например, можно назначить префикс ко всем маршрутам сгруппированных по имени и начинающийхся с admin. Префикс берётся в точности, как указан. Поэтому убедитесь в том, что точка . включена в указанный префикс:
Route::name('admin.')->group(function () {
Route::get('users', function () {
// Route assigned name "admin.users"...
})->name('users');
});
Связь маршрута и модели:
При введение идентификатора модели в маршрут или действие контроллера, необходимо убедиться в том, что модель соответсвует идентификатору. Связь маршрута и модели в Ларавел даёт возможность автоматически внедрять модели в маршрут. Например, вместо того чтобы внедрять идентификатор пользователя, можно внедрить модель, которая будет соответствовать данному идентификатору.
Неявная привязка:
Модели Eloquent, которые определены в маршрутах или действиях котроллерах, соответсвуют имени переменной, указанной в сегменте маршрута. Например:
Route::get('api/users/{user}', function (App\User $user) {
return $user->email;
});
Переменная $user вписана как App\User модель Eloquent и имя переменной соотвествует имени сегмента {user}, Laravel автоматически введёт сущность модели, которая совпадает по идентификатору и щзначение из запроса. В случае, если не удастся найти соответсвующую модель в базе данных, 404 HTTP ответ сгенерируется автоматически.
Настройка имени ключа:
Чтобы связать модель не с идентификатором, а другим столбцом из базы данных, необходимо перезаписать поле в модели Eloquent методом getRouteKeyName:
/**
* Get the route key for the model.
*
* @return string
*/
public function getRouteKeyName()
{
return 'slug';
}
Явная привязка:
Чтобы зарегистрировать явную привязку, используйте модель и укажите класс для данного параметра. Для этого в классе RouteServiceProvider точно укажите модель:
public function boot()
{
parent::boot();
Route::model('user', App\User::class);
}
После определите маршрут, который содержит парметр {user}.
Route::get('profile/{user}', function (App\User $user) {
//
});
После того как мы привязали все параметры к модели App\User, модель будет внедрена в путь. Поэтому запрос profile/1 внедрит модель User из базы данных с идентификатором 1.
Если указанному идентификатору не найдётся записть в базе данных, то HTTP ответ 404 сгенерируется автоматически.
Настройка логики принятия решений:
Если вы хотите использовать свою логику работы, то используйте Route::bind метод. В результате чего, вы сможете получить сущность класса, которая должна быть внедрена в маршрут.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
parent::boot();
Route::bind('user', function ($value) {
return App\User::where('name', $value)->first() ?? abort(404);
});
}
Как альтернатива, можно перезаписать метод resolveRouteBinding в Eloquent модели. Этот метод получит значение сегмента и вернёт объект, который и будет внедрён в маршрут.
/**
* Retrieve the model for a bound value.
*
* @param mixed $value
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveRouteBinding($value)
{
return $this->where('name', $value)->first() ?? abort(404);
}
Маршруты ошибки:
Если ни один из маршрутов не соответствует запросу, то можно испоьзовать метод Route::fallback, чтобы определить порядок действий в этом случае. По умолчанию, такие запросы автоматически сгенерируют ответ ввиде страницы 404, и не приведит к ошибке приложеиня. После того, как вы определили правила поведения в routes/web.php файле, все запросы будут следовать этой логике. Вы можете добавить обработчик в промежуточном слое по желанию:
Route::fallback(function () {
//
});
Ограничение числа запросов:
В Laravel можно испоьзовать методологию ограничение числа запросов к маршруту или группе маршрутов. Для этого необходимо прописать к маршруту промежуточный слой с методом throttle, который включает 2 параметра: колчество запросов и временной интервал в минутах. Определим, что авторизированный пользователь может делать 60 запросов в минуту к группе маршрутов:
Route::middleware('auth:api', 'throttle:60,1')->group(function () {
Route::get('/user', function () {
//
});
});
Динамическое ограничение:
Можно указать динамический максимум запросов, основанный на атрибуте в модели. Например, если вы модель содержит rate_limit атрибут, то вы можете передать значение в промежуточный слой, чтобы высчитать максимум запросов:
Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
Route::get('/user', function () {
//
});
});
Имитация методов в формах:
HTML формы не поддерживают методы PUT, PATCH или DELETE. Поэтому, чтобы определить PUT, PATCH или DELETE маршруты в HTML форме, вам необходимо добавть скрытое поле _method в форму. Значение, которое указано в поле, будет использовано как HTTP метод:
<form action="/foo/bar" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
Вы можете использовать @method в шаблонизаторе Blade, чтобы сгенерировать _method поле ввода.
<form action="/foo/bar" method="POST">
@method('PUT')
@csrf
</form>
Текущий адрес:
Можете использовать current, currentRouteName и currentRouteAction методы, чтобы получить информацию о текущем запросе.
$route = Route::current();
$name = Route::currentRouteName();
$action = Route::currentRouteAction();
Обратитесь к API документации, чтобы получить список всех команд и методов.