Skip to content

3.1. Маршрутизация

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

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

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

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

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

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

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

1.1.1. API-маршруты

Если ваше приложение также будет предоставлять API без сохранения состояния, вы можете включить маршрутизацию API с помощью команды Artisan install:api:

php artisan install:api

Команда install:api устанавливает Laravel Sanctum, который предоставляет надежный и в то же время простой механизм аутентификации с использованием API-токенов. Он может быть использован для аутентификации сторонних потребителей API, SPA или мобильных приложений. Кроме того, команда install:api создает файл routes/api.php:

Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');

Маршруты в файле routes/api.php являются статическими и назначаются в группу посредников api. Кроме того, к этим маршрутам автоматически применяется префикс URI /api, поэтому вам не нужно вручную добавлять его к каждому маршруту в файле. Вы можете изменить этот префикс, отредактировав файл bootstrap/app.php вашего приложения:

->withRouting(
api: __DIR__.'/../routes/api.php',
apiPrefix: 'api/admin',
// ...
)

1.1.2. Доступные методы маршрутизатора

Маршрутизатор позволяет регистрировать маршруты, которые обрабатывают любые 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 () {
// ...
});
lightbulb

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

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

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

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

1.1.4. Защита от CSRF

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

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

1.2. Маршруты перенаправления

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

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

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

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

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

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

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

1.3. Маршруты представлений

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

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

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

1.4. Cписок маршрутов

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

php artisan route:list

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

php artisan route:list -v
 
# Раскрытие групп middleware...
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

1.5. Кастомизация маршрутизации

По умолчанию маршруты вашего приложения настраиваются и загружаются в файле bootstrap/app.php:

<?php
 
use Illuminate\Foundation\Application;
 
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)->create();

Однако иногда вам может потребоваться определить совершенно новый файл для хранения подмножества маршрутов вашего приложения. Для этого вы можете передать замыкание then в метод withRouting. В этом замыкании вы можете зарегистрировать любые дополнительные маршруты, необходимые для вашего приложения:

use Illuminate\Support\Facades\Route;
 
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
then: function () {
Route::middleware('api')
->prefix('webhooks')
->name('webhooks.')
->group(base_path('routes/webhooks.php'));
},
)

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

use Illuminate\Support\Facades\Route;
 
->withRouting(
commands: __DIR__.'/../routes/console.php',
using: function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
 
Route::middleware('web')
->group(base_path('routes/web.php'));
},
)

2. Параметры маршрутов

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

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

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

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

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

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

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

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

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

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

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

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

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

Вы можете ограничить формат параметров маршрута с помощью метода 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']);
 
Route::get('/category/{category}', function (string $category) {
// ...
})->whereIn('category', CategoryEnum::cases());

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

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

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

use Illuminate\Support\Facades\Route;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Route::pattern('id', '[0-9]+');
}

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

Route::get('/user/{id}', function (string $id) {
// Only executed if {id} is numeric...
});

2.3.2. Кодированные прямых слешэй

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

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

Кодированные прямых слешей поддерживется только в последнем сегменте маршрута.