1. Основы
  2. Маршрутизация

Присоединяйся к нашему Telegram сообществу @webblend!

Здесь ты найдешь сниппеты по Laravel и полезные советы по веб-разработке.

Основная маршрутизация

Наиболее базовые маршруты Laravel принимают URI и замыкание, предоставляя очень простой и выразительный метод определения маршрутов и поведения без сложных файлов конфигурации маршрутизации:

use Illuminate\Support\Facades\Route;
 
Route::get('/greeting', function () {
return 'Hello World';
});

Файлы маршрутов по умолчанию

Все маршруты Laravel определяются в ваших файлах маршрутов, которые находятся в каталоге routes. Эти файлы автоматически загружаются App\Providers\RouteServiceProvider вашего приложения. Файл routes/web.php определяет маршруты, предназначенные для вашего веб-интерфейса. Этим маршрутам назначается группа промежуточных обработчиков web, которая предоставляет функции, такие как состояние сеанса и защита от CSRF. Маршруты в файле routes/api.php являются бессостоятельными и им назначается группа промежуточных обработчиков api.

Для большинства приложений вы начнете с определения маршрутов в файле routes/web.php. Маршруты, определенные в routes/web.php, можно получить, введя URL определенного маршрута в вашем браузере. Например, вы можете получить доступ к следующему маршруту, перейдя по адресу http://example.com/user в вашем браузере:

use App\Http\Controllers\UserController;
 
Route::get('/user', [UserController::class, 'index']);

Маршруты, определенные в файле routes/api.php, вложены в группу маршрутов через RouteServiceProvider. Внутри этой группы префикс /api автоматически применяется, поэтому вам не нужно вручную применять его ко всем маршрутам в файле. Вы можете изменить префикс и другие параметры группы маршрутов, изменив класс 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);

Иногда вам может потребоваться зарегистрировать маршрут, который реагирует на несколько HTTP-глаголов. Вы можете сделать это с использованием метода match. Или вы можете даже зарегистрировать маршрут, который реагирует на все HTTP-глаголы, используя метод any:

Route::match(['get', 'post'], '/', function () {
// ...
});
 
Route::any('/', function () {
// ...
});

Примечание При определении нескольких маршрутов с одинаковым URI маршруты с использованием методов get, post, put, patch, delete и options должны быть определены перед маршрутами с использованием методов any, match и redirect. Это обеспечивает сопоставление входящего запроса с правильным маршрутом.

Внедрение зависимостей

Вы можете указать тип любых зависимостей, необходимых для вашего маршрута, в сигнатуре обратного вызова маршрута. Объявленные зависимости будут автоматически разрешены и внедрены в обратный вызов контейнером служб Laravel service container. Например, вы можете указать тип Illuminate\Http\Request, чтобы автоматически внедрить текущий HTTP-запрос в обратный вызов маршрута:

use Illuminate\Http\Request;
 
Route::get('/users', function (Request $request) {
// ...
});

Защита CSRF

Помните, что любые HTML-формы, указывающие на маршруты с методами POST, PUT, PATCH или DELETE, определенные в файлах маршрутов web, должны включать поле с токеном CSRF. В противном случае запрос будет отклонен. Вы можете узнать больше о защите CSRF в документации по CSRF:

<form method="POST" action="/profile">
@csrf
...
</form>

Перенаправление маршрутов

Если вы определяете маршрут, который перенаправляется на другой URI, вы можете использовать метод Route::redirect. Этот метод предоставляет удобный ярлык, чтобы вам не пришлось определять полный маршрут или контроллер для выполнения простого перенаправления:

Route::redirect('/here', '/there');

По умолчанию Route::redirect возвращает статусный код 302. Вы можете настроить код состояния, используя третий необязательный параметр:

Route::redirect('/here', '/there', 301);

Или вы можете использовать метод Route::permanentRedirect для возврата статусного кода 301:

Route::permanentRedirect('/here', '/there');

Внимание При использовании параметров маршрута в маршрутах перенаправления следующие параметры зарезервированы Laravel и не могут быть использованы: destination и status.

Просмотр маршрутов

Если ваш маршрут должен возвращать только представление, вы можете использовать метод Route::view. Как и метод redirect, этот метод предоставляет простой ярлык, чтобы вам не пришлось определять полный маршрут или контроллер. Метод view принимает URI в качестве первого аргумента и имя представления в качестве второго аргумента. Кроме того, вы можете предоставить массив данных для передачи представлению в качестве третьего аргумента (необязательно):

Route::view('/welcome', 'welcome');
 
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

Внимание При использовании параметров маршрута в маршрутах представлений следующие параметры зарезервированы Laravel и не могут быть использованы: view, data, status и headers.

Список маршрутов

Команда Artisan route:list легко предоставляет обзор всех маршрутов, определенных в вашем приложении:

php artisan route:list

По умолчанию маршрутное промежуточное ПО, назначенное каждому маршруту, не отображается в выводе route:list. Однако вы можете указать Laravel отображать промежуточное ПО маршрута и имена групп промежуточного ПО, добавив опцию -v к команде:

php artisan route:list -v
 
# Expand middleware groups...
php artisan route:list -vv

Вы также можете указать Laravel отображать только те маршруты, которые начинаются с определенного URI:

php artisan route:list --path=api

Кроме того, вы можете указать Laravel скрывать любые маршруты, определенные сторонними пакетами, предоставив опцию --except-vendor при выполнении команды route:list:

php artisan route:list --except-vendor

Точно так же вы можете указать Laravel отображать только маршруты, определенные сторонними пакетами, предоставив опцию --only-vendor при выполнении команды route:list:

php artisan route:list --only-vendor

Параметры маршрута

Обязательные параметры

Иногда вам нужно захватывать сегменты URI в вашем маршруте. Например, вы можете захватить ID пользователя из URL. Вы можете сделать это, определив параметры маршрута:

Route::get('/user/{id}', function (string $id) {
return 'User '.$id;
});

Вы можете определять столько параметров маршрута, сколько требуется для вашего маршрута:

Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) {
// ...
});

Параметры маршрута всегда заключаются в фигурные скобки {} и должны состоять из буквенных символов. Также символы подчеркивания (_) допустимы в именах параметров маршрута. Параметры маршрута внедряются в обратные вызовы / контроллеры маршрута на основе их порядка - имена аргументов обратного вызова / контроллера не имеют значения.

Параметры и внедрение зависимостей

Если у вашего маршрута есть зависимости, которые вы хотели бы, чтобы контейнер служб Laravel автоматически внедрял в обратный вызов вашего маршрута, вы должны перечислить параметры вашего маршрута после ваших зависимостей:

use Illuminate\Http\Request;
 
Route::get('/user/{id}', function (Request $request, string $id) {
return 'User '.$id;
});

Необязательные параметры

Иногда вам может потребоваться указать параметр маршрута, который не всегда присутствует в URI. Вы можете сделать это, добавив знак ? после имени параметра. Обязательно предоставьте переменной соответствующее значение по умолчанию:

Route::get('/user/{name?}', function (?string $name = null) {
return $name;
});
 
Route::get('/user/{name?}', function (?string $name = 'John') {
return $name;
});

Ограничения с регулярными выражениями

Вы можете ограничивать формат ваших параметров маршрута с использованием метода where на экземпляре маршрута. Метод where принимает имя параметра и регулярное выражение, определяющее, как параметр должен быть ограничен:

Route::get('/user/{name}', function (string $name) {
// ...
})->where('name', '[A-Za-z]+');
 
Route::get('/user/{id}', function (string $id) {
// ...
})->where('id', '[0-9]+');
 
Route::get('/user/{id}/{name}', function (string $id, string $name) {
// ...
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

Для удобства некоторые широко используемые шаблоны регулярных выражений имеют вспомогательные методы, позволяющие быстро добавлять ограничения шаблона к вашим маршрутам:

Route::get('/user/{id}/{name}', function (string $id, string $name) {
// ...
})->whereNumber('id')->whereAlpha('name');
 
Route::get('/user/{name}', function (string $name) {
// ...
})->whereAlphaNumeric('name');
 
Route::get('/user/{id}', function (string $id) {
// ...
})->whereUuid('id');
 
Route::get('/user/{id}', function (string $id) {
//
})->whereUlid('id');
 
Route::get('/category/{category}', function (string $category) {
// ...
})->whereIn('category', ['movie', 'song', 'painting']);

Если входящий запрос не соответствует ограничениям шаблона маршрута, будет возвращен HTTP-ответ с кодом 404.

Глобальные ограничения

Если вы хотите, чтобы параметр маршрута всегда ограничивался заданным шаблоном регулярного выражения, вы можете использовать метод pattern. Вы должны определить эти шаблоны в методе boot вашего класса App\Providers\RouteServiceProvider:

/**
* Определите привязки модели к маршруту, фильтры шаблонов и т. д.
*/
public function boot(): void
{
Route::pattern('id', '[0-9]+');
}

После того как шаблон был определен, он автоматически применяется ко всем маршрутам с использованием этого имени параметра:

Route::get('/user/{id}', function (string $id) {
// Выполняется только в том случае, если {id} является числовым...
});

Закодированные косые черты вперед

Компонент маршрутизации Laravel позволяет использовать все символы, кроме /, в значениях параметров маршрута. Вы должны явно разрешить / в вашем заполнителе, используя регулярное выражение с условием where:

Route::get('/search/{search}', function (string $search) {
return $search;
})->where('search', '.*');

Внимание Закодированные косые черты поддерживаются только в пределах последнего сегмента маршрута.

Именованные маршруты

Именованные маршруты позволяют удобно создавать URL или перенаправления для конкретных маршрутов. Вы можете указать имя для маршрута, добавив метод name к определению маршрута:

Route::get('/user/profile', function () {
// ...
})->name('profile');

Вы также можете указать имена маршрутов для действий контроллера:

Route::get(
'/user/profile',
[UserProfileController::class, 'show']
)->name('profile');

Внимание Имена маршрутов всегда должны быть уникальными.

Генерация URL для именованных маршрутов

После присвоения имени определенному маршруту, вы можете использовать имя маршрута при создании URL или перенаправлений с помощью вспомогательных функций Laravel route и redirect:

// Генерация URL...
$url = route('profile');
 
// Генерация перенаправлений...
return redirect()->route('profile');
 
return to_route('profile');

Если именованный маршрут определяет параметры, вы можете передать параметры вторым аргументом функции route. Указанные параметры будут автоматически вставлены в сгенерированный URL в соответствующие позиции:

Route::get('/user/{id}/profile', function (string $id) {
// ...
})->name('profile');
 
$url = route('profile', ['id' => 1]);

Если вы передаете дополнительные параметры в массиве, эти пары ключ / значение автоматически добавляются в строку запроса сгенерированного URL:

Route::get('/user/{id}/profile', function (string $id) {
// ...
})->name('profile');
 
$url = route('profile', ['id' => 1, 'photos' => 'yes']);
 
// /user/1/profile?photos=yes

Примечание Иногда вы можете захотеть указать значения по умолчанию для параметров URL на уровне запроса, таких как текущая локаль. Для этого вы можете использовать метод URL::defaults.

Исследование текущего маршрута

Если вы хотите определить, был ли текущий запрос направлен на определенный именованный маршрут, вы можете использовать метод named на экземпляре маршрута. Например, вы можете проверить имя текущего маршрута из промежуточного ПО маршрута:

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
 
/**
* Обрабатывает входящий запрос.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if ($request->route()->named('profile')) {
// ...
}
 
return $next($request);
}

Группы маршрутов

Группы маршрутов позволяют вам совместно использовать атрибуты маршрута, такие как промежуточное ПО, для большого числа маршрутов, не нуждаясь в определении этих атрибутов для каждого отдельного маршрута.

Вложенные группы пытаются интеллектуально "сливать" атрибуты с родительской группой. Промежуточное ПО и условия where сливаются, а имена и префиксы добавляются. Разделители пространств и слеши в префиксах URI добавляются автоматически при необходимости.

Промежуточное ПО

Для назначения промежуточных обработчиков всем маршрутам в группе вы можете использовать метод middleware перед определением группы. Промежуточные обработчики выполняются в том порядке, в котором они указаны в массиве:

Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// Использует первый и второй middleware...
});
 
Route::get('/user/profile', function () {
// Использует первый и второй middleware...
});
});

Контроллеры

Если группа маршрутов использует одинаковый контроллер, вы можете использовать метод controller для определения общего контроллера для всех маршрутов в группе. Затем при определении маршрутов вам нужно только предоставить метод контроллера, который они вызывают:

use App\Http\Controllers\OrderController;
 
Route::controller(OrderController::class)->group(function () {
Route::get('/orders/{id}', 'show');
Route::post('/orders', 'store');
});

Маршрутизация поддоменов

Группы маршрутов также могут использоваться для маршрутизации поддоменов. Поддомены могут быть назначены параметрам маршрута так же, как и URI маршрута, позволяя захватывать часть поддомена для использования в вашем маршруте или контроллере. Поддомен может быть указан с использованием метода domain перед определением группы:

Route::domain('{account}.example.com')->group(function () {
Route::get('user/{id}', function (string $account, string $id) {
// ...
});
});

Внимание Для обеспечения доступности маршрутов поддомена рекомендуется регистрировать маршруты поддомена перед регистрацией маршрутов корневого домена. Это предотвратит перезапись маршрутов корневого домена маршрутами поддомена с тем же URI.

Префиксы маршрутов

Метод prefix может быть использован для добавления префикса каждому маршруту в группе с заданным URI. Например, вы можете захотеть добавить префикс admin ко всем URI маршрутов в группе:

Route::prefix('admin')->group(function () {
Route::get('/users', function () {
// Совпадает с URL "/admin/users"
});
});

Префиксы имен маршрутов

Метод name может быть использован для добавления префикса каждому имени маршрута в группе с заданной строкой. Например, вы можете захотеть добавить префикс admin ко всем именам маршрутов в группе. Указанная строка добавляется к имени маршрута точно так, как она указана, поэтому не забудьте добавить завершающий символ . в префикс:

Route::name('admin.')->group(function () {
Route::get('/users', function () {
// Маршрут получает имя "admin.users"...
})->name('users');
});

Привязка модели к маршруту

При внедрении идентификатора модели в маршрут или действие контроллера вы часто будете запрашивать базу данных для получения модели, которая соответствует этому идентификатору. Привязка моделей маршрута Laravel предоставляет удобный способ автоматически внедрять экземпляры моделей непосредственно в ваши маршруты. Например, вместо внедрения идентификатора пользователя вы можете внедрить целый экземпляр модели User, который соответствует данному идентификатору.

Неявная привязка

Laravel автоматически разрешает модели Eloquent, определенные в маршрутах или действиях контроллеров, чьи типизированные по типу переменных имена соответствуют имени сегмента маршрута. Например:

use App\Models\User;
 
Route::get('/users/{user}', function (User $user) {
return $user->email;
});

Поскольку переменная $user типизирована как модель Eloquent App\Models\User и имя переменной совпадает с сегментом URI {user}, Laravel автоматически вставит экземпляр модели, который имеет идентификатор, соответствующий соответствующему значению из URI запроса. Если соответствующий экземпляр модели не найден в базе данных, автоматически будет сгенерирован HTTP-ответ с кодом 404.

Конечно же, неявная привязка также возможна при использовании методов контроллера. Опять же, обратите внимание, что сегмент URI {user} совпадает с переменной $user в контроллере, которая содержит типизированный тип App\Models\User:

use App\Http\Controllers\UserController;
use App\Models\User;
 
// Определение маршрута...
Route::get('/users/{user}', [UserController::class, 'show']);
 
// Определение метода контроллера...
public function show(User $user)
{
return view('user.profile', ['user' => $user]);
}

Модели со мягким удалением

Как правило, неявная привязка моделей не будет извлекать модели, которые были мягко удалены. Тем не менее, вы можете научить неявную привязку извлекать эти модели, добавив метод withTrashed к определению вашего маршрута:

use App\Models\User;
 
Route::get('/users/{user}', function (User $user) {
return $user->email;
})->withTrashed();

Настройка ключа

Иногда вы можете захотеть разрешить модели Eloquent, используя столбец отличный от id. Для этого вы можете указать столбец в определении параметра маршрута:

use App\Models\Post;
 
Route::get('/posts/{post:slug}', function (Post $post) {
return $post;
});

Если вы хотите, чтобы привязка модели всегда использовала столбец базы данных, отличный от id, при извлечении данного класса модели, вы можете переопределить метод getRouteKeyName в модели Eloquent:

/**
* Получить ключ маршрута для модели.
*/
public function getRouteKeyName(): string
{
return 'slug';
}

Настройка пользовательских ключей и областей

При неявной привязке нескольких моделей Eloquent в одном определении маршрута вы можете захотеть ограничить вторую модель Eloquent так, чтобы она должна была быть дочерней по отношению к предыдущей модели Eloquent. Например, рассмотрим это определение маршрута, которое извлекает сообщение в блоге по слагу для определенного пользователя:

use App\Models\Post;
use App\Models\User;
 
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
});

При использовании неявной привязки вложенной маршрутизации с пользовательским ключом, Laravel автоматически ограничит запрос для извлечения вложенной модели ее родителем с использованием соглашений для угадывания имени отношения на родителе. В этом случае предполагается, что у модели User есть отношение с именем posts (во множественном числе относительно имени параметра маршрута), которое может быть использовано для извлечения модели Post.

Если вы хотите, вы можете научить Laravel ограничивать "дочерние" привязки даже в том случае, если пользовательский ключ не предоставлен. Для этого вы можете вызвать метод scopeBindings при определении вашего маршрута:

use App\Models\Post;
use App\Models\User;
 
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
return $post;
})->scopeBindings();

Или вы можете научить целую группу определений маршрутов использовать ограниченные привязки:

Route::scopeBindings()->group(function () {
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
return $post;
});
});

Точно так же вы можете явно научить Laravel не ограничивать привязки, вызвав метод withoutScopedBindings:

Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
})->withoutScopedBindings();

Настройка поведения отсутствующей модели

Как правило, если неявно связанная модель не найдена, будет сгенерирован ответ HTTP с кодом 404. Однако вы можете настроить это поведение, вызвав метод missing при определении вашего маршрута. Метод missing принимает замыкание, которое будет вызвано, если не удается найти неявно связанную модель:

use App\Http\Controllers\LocationsController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
 
Route::get('/locations/{location:slug}', [LocationsController::class, 'show'])
->name('locations.view')
->missing(function (Request $request) {
return Redirect::route('locations.index');
});

Неявная привязка перечислений

PHP 8.1 представил поддержку перечислений. Дополняя эту функцию, Laravel позволяет вам указать перечисление со строковым значением в типе вашего определения маршрута, и Laravel будет вызывать маршрут только в том случае, если этот сегмент маршрута соответствует допустимому значению перечисления. В противном случае автоматически будет возвращен ответ HTTP с кодом 404. Например, учитывая следующее перечисление:

<?php
 
namespace App\Enums;
 
enum Category: string
{
case Fruits = 'fruits';
case People = 'people';
}

Вы можете определить маршрут, который будет вызван только в том случае, если сегмент маршрута {category} равен fruits или people. В противном случае Laravel вернет ответ HTTP с кодом 404:

use App\Enums\Category;
use Illuminate\Support\Facades\Route;
 
Route::get('/categories/{category}', function (Category $category) {
return $category->value;
});

Явная привязка

Для использования привязки модели вам не обязательно использовать неявное, основанное на соглашениях разрешение модели. Вы также можете явно определить, как параметры маршрута соотносятся с моделями. Чтобы зарегистрировать явную привязку, используйте метод model маршрутизатора, чтобы указать класс для заданного параметра. Вы должны определять ваши явные привязки моделей в начале метода boot вашего класса RouteServiceProvider:

use App\Models\User;
use Illuminate\Support\Facades\Route;
 
/**
* Определите привязки модели к маршруту, фильтры шаблонов и т. д.
*/
public function boot(): void
{
Route::model('user', User::class);
 
// ...
}

Затем определите маршрут, содержащий параметр {user}:

use App\Models\User;
 
Route::get('/users/{user}', function (User $user) {
// ...
});

Поскольку мы привязали все параметры {user} к модели App\Models\User, в маршрут будет внедрен экземпляр этого класса. Так, например, запрос к users/1 внедрит экземпляр User из базы данных с идентификатором 1.

Если соответствующий экземпляр модели не найден в базе данных, автоматически будет сгенерирован HTTP-ответ с кодом 404.

Настройка логики разрешения

Если вы хотите определить свою собственную логику разрешения привязки модели, вы можете использовать метод Route::bind. Замыкание, передаваемое методу bind, получит значение сегмента URI и должно вернуть экземпляр класса, который должен быть внедрен в маршрут. Опять же, это настраивается в методе boot вашего RouteServiceProvider приложения:

use App\Models\User;
use Illuminate\Support\Facades\Route;
 
/**
* Определите привязки модели к маршруту, фильтры шаблонов и т. д.
*/
public function boot(): void
{
Route::bind('user', function (string $value) {
return User::where('name', $value)->firstOrFail();
});
 
// ...
}

Кроме того, вы можете переопределить метод resolveRouteBinding в своей модели Eloquent. Этот метод получит значение сегмента URI и должен вернуть экземпляр класса, который должен быть внедрен в маршрут:

/**
* Получите модель для связанного значения.
*
* @param mixed $value
* @param string|null $field
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveRouteBinding($value, $field = null)
{
return $this->where('name', $value)->firstOrFail();
}

Если маршрут использует ограничение неявной привязки, метод resolveChildRouteBinding будет использоваться для разрешения дочерней привязки родительской модели:

/**
* Получите дочернюю модель для связанного значения.
*
* @param string $childType
* @param mixed $value
* @param string|null $field
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveChildRouteBinding($childType, $value, $field)
{
return parent::resolveChildRouteBinding($childType, $value, $field);
}

Запасные маршруты

Используя метод Route::fallback, вы можете определить маршрут, который будет выполнен, когда ни один другой маршрут не соответствует входящему запросу. Обычно необработанные запросы автоматически отображают страницу "404" через обработчик исключений вашего приложения. Однако, поскольку вы обычно будете определять маршрут fallback в файле routes/web.php, к нему будут применяться все middleware в группе middleware web. Вы можете свободно добавлять дополнительные middleware к этому маршруту при необходимости:

Route::fallback(function () {
// ...
});

Внимание Резервный маршрут должен всегда быть последним зарегистрированным маршрутом вашим приложением.

Ограничение по частоте

Определение ограничителей частоты

Laravel включает мощные и настраиваемые службы ограничения скорости, которые вы можете использовать для ограничения объема трафика для заданного маршрута или группы маршрутов. Для начала вам следует определить конфигурации ограничителя скорости, соответствующие потребностям вашего приложения.

Обычно ограничители скорости определяются внутри метода boot класса App\Providers\RouteServiceProvider вашего приложения. Фактически, этот класс уже включает определение ограничителя скорости, которое применяется к маршрутам в файле routes/api.php вашего приложения:

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
 
/**
* Определите привязки модели к маршруту, фильтры шаблонов и другие настройки маршрута.
*/
protected function boot(): void
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
 
// ...
}

Ограничители скорости определяются с использованием метода for фасада RateLimiter. Метод for принимает имя ограничителя скорости и замыкание, которое возвращает конфигурацию лимита, которая должна применяться к маршрутам, назначенным ограничителю скорости. Конфигурации лимита являются экземплярами класса Illuminate\Cache\RateLimiting\Limit. Этот класс содержит полезные методы "строителя", чтобы вы могли быстро определить свой лимит. Имя ограничителя скорости может быть любой строкой, которую вы выберете:

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
 
/**
* Определите привязки модели к маршруту, фильтры шаблонов и другие настройки маршрута.
*/
protected function boot(): void
{
RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000);
});
 
// ...
}

Если входящий запрос превышает указанный лимит скорости, Laravel автоматически вернет ответ с HTTP-статус-кодом 429. Если вы хотите определить свой собственный ответ, который должен быть возвращен при ограничении скорости, вы можете использовать метод response:

RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000)->response(function (Request $request, array $headers) {
return response('Custom response...', 429, $headers);
});
});

Поскольку обратные вызовы ограничителей скорости получают экземпляр входящего запроса HTTP, вы можете динамически строить соответствующий лимит скорости на основе входящего запроса или аутентифицированного пользователя:

RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100);
});

Сегментация ограничителей частоты

Иногда вам может потребоваться разделить лимиты скорости по какому-то произвольному значению. Например, вы можете разрешить пользователям получить доступ к заданному маршруту 100 раз в минуту на один IP-адрес. Для этого вы можете использовать метод by при создании лимита скорости:

RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100)->by($request->ip());
});

Для иллюстрации этой функции на другом примере мы можем ограничить доступ к маршруту 100 раз в минуту на один идентификатор аутентифицированного пользователя или 10 раз в минуту на один IP-адрес для гостей:

RateLimiter::for('uploads', function (Request $request) {
return $request->user()
? Limit::perMinute(100)->by($request->user()->id)
: Limit::perMinute(10)->by($request->ip());
});

Несколько ограничителей частоты

При необходимости вы можете вернуть массив лимитов скорости для заданной конфигурации ограничителя скорости. Каждый лимит будет оценен для маршрута в порядке их размещения в массиве:

RateLimiter::for('login', function (Request $request) {
return [
Limit::perMinute(500),
Limit::perMinute(3)->by($request->input('email')),
];
});

Привязка ограничителей частоты к маршрутам

Ограничители скорости могут быть присоединены к маршрутам или группам маршрутов с использованием промежуточного программного обеспечения throttle. Промежуточное программное обеспечение throttle принимает имя ограничителя скорости, который вы хотите назначить маршруту:

Route::middleware(['throttle:uploads'])->group(function () {
Route::post('/audio', function () {
// ...
});
 
Route::post('/video', function () {
// ...
});
});

Ограничение с помощью Redis

Обычно промежуточное программное обеспечение throttle сопоставляется с классом Illuminate\Routing\Middleware\ThrottleRequests. Это сопоставление определено в ядре HTTP вашего приложения (App\Http\Kernel). Однако, если вы используете Redis в качестве драйвера кэша вашего приложения, вы можете захотеть изменить это сопоставление, чтобы использовать класс Illuminate\Routing\Middleware\ThrottleRequestsWithRedis. Этот класс более эффективно управляет ограничением скорости с использованием Redis:

'throttle' => \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class,

Обман метода формы

HTML-формы не поддерживают действия PUT, PATCH или DELETE. Так что, при определении маршрутов PUT, PATCH или DELETE, вызываемых из HTML-формы, вам нужно добавить скрытое поле _method в форму. Значение, отправляемое с полем _method, будет использоваться как метод HTTP-запроса:

<form action="/example" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

Для удобства вы можете использовать директиву Blade @method Blade, чтобы создать скрытое поле _method:

<form action="/example" method="POST">
@method('PUT')
@csrf
</form>

Доступ к текущему маршруту

Вы можете использовать методы current, currentRouteName и currentRouteAction из фасада Route для доступа к информации о маршруте, обрабатывающем входящий запрос:

use Illuminate\Support\Facades\Route;
 
$route = Route::current(); // Illuminate\Routing\Route
$name = Route::currentRouteName(); // string
$action = Route::currentRouteAction(); // string

Вы можете обратиться к документации API как основного класса фасада маршрута, так и экземпляра маршрута, чтобы ознакомиться со всеми методами, доступными в классах маршрутизатора и маршрута.

Междоменный обмен ресурсами (CORS)

Laravel может автоматически отвечать на CORS OPTIONS HTTP-запросы с настройками, которые вы настраиваете. Все настройки CORS можно настроить в файле конфигурации вашего приложения config/cors.php. Запросы OPTIONS автоматически обрабатываются промежуточным ПО HandleCors, который включен по умолчанию в ваш глобальный стек промежуточных программ. Глобальный стек промежуточных программ находится в ядре HTTP вашего приложения (App\Http\Kernel).

Примечание Для получения дополнительной информации о CORS и заголовках CORS обратитесь к документации MDN по CORS.

Кэширование маршрутов

При развертывании вашего приложения в производстве рекомендуется использовать кэш маршрутов Laravel. Использование кэша маршрутов значительно уменьшит время, необходимое для регистрации всех маршрутов вашего приложения. Для создания кэша маршрутов выполните команду Artisan route:cache:

php artisan route:cache

После выполнения этой команды ваш кэшированный файл маршрутов будет загружен при каждом запросе. Помните, что при добавлении новых маршрутов вам нужно будет создать свежий кэш маршрутов. Из-за этого команду route:cache рекомендуется запускать только во время развертывания проекта.

Вы можете использовать команду route:clear для очистки кэша маршрутов:

php artisan route:clear