Маршруты: связь URL и кода
Маршрут — это правило, которое говорит Laravel: «когда придёт запрос на этот адрес, выполни вот этот код».
Суть: в файле
routes/web.phpвы связываете URL и HTTP-метод с обработчиком — замыканием или методом контроллера. Это «карта» вашего приложения.
Когда браузер запрашивает страницу, Laravel должен понять, какой код её обслуживает. За это отвечают маршруты. По сути это таблица соответствий: «адрес /products при методе GET — покажи список товаров». Все веб-маршруты живут в файле routes/web.php, и именно с него начинается любое приложение.
Маршруты задаются через статический класс Route. Самый частый метод — Route::get() для отображения страниц. Есть и другие: post для отправки форм, put/patch для обновления, delete для удаления. Эти методы соответствуют HTTP-глаголам и формируют основу REST-подхода.
Базовый синтаксис
<?php
use Illuminate\Support\Facades\Route;
// Простой маршрут с замыканием
Route::get('/', function () {
return 'Привет, Laravel!';
});
// Маршрут, возвращающий шаблон
Route::get('/about', function () {
return view('about');
});
// Маршрут с параметром
Route::get('/products/{id}', function (int $id) {
return 'Товар номер '.$id;
});Фигурные скобки {id} — это параметр маршрута: его значение из URL автоматически попадёт в аргумент функции. Запрос /products/42 вернёт «Товар номер 42».
Как работает под капотом
При старте Laravel читает все маршруты и строит из них таблицу. Когда приходит запрос, роутер перебирает маршруты сверху вниз и берёт первый совпавший по адресу и методу. Если совпадения нет — отдаёт ошибку 404.
Запрос: GET /products/42
|
v
Роутер сверяет с таблицей:
+------------------------------+
| GET / -> главная |
| GET /about -> about |
| GET /products/{id} <== СОВПАЛО, id=42
| POST /products -> store |
+------------------------------+
|
v
Запуск обработчика с id=42
Важно понимать, что метод тоже учитывается: GET /products и POST /products — это два разных маршрута с разными обработчиками. Смоделируем работу роутера на Python с учётом метода и параметров.
Попробуй сам ▶
# Роутер, учитывающий метод и параметр {id}
routes = [
('GET', '/', lambda **k: 'Главная'),
('GET', '/products', lambda **k: 'Список товаров'),
('GET', '/products/id', lambda id=None: f'Товар {id}'),
('POST', '/products', lambda **k: 'Товар создан'),
]
def dispatch(method, url):
parts = url.strip('/').split('/')
for m, pattern, handler in routes:
pp = pattern.strip('/').split('/')
if m == method and len(pp) == len(parts):
params, ok = {}, True
for a, b in zip(pp, parts):
if a == 'id': params['id'] = b
elif a != b: ok = False
if ok:
return handler(**params)
return '404'
print(dispatch('GET', '/products/42'))
print(dispatch('POST', '/products'))
print(dispatch('GET', '/unknown'))
Частые ошибки
- Неверный порядок маршрутов. Если общий маршрут
/products/{id}стоит выше конкретного/products/new, второй никогда не сработает — первый перехватит. - Путать GET и POST. Форма отправляет POST, а маршрут описан как GET — будет ошибка 405 (метод не разрешён).
- Логика в замыканиях. Замыкания удобны для простых страниц, но для реальной логики используйте контроллеры.
Best practices
- Для всего, кроме простейших страниц, направляйте маршрут в контроллер, а не в замыкание.
- Давайте маршрутам имена через
->name()— это упростит генерацию ссылок. - Запускайте
php artisan route:list, чтобы увидеть все маршруты приложения.
Маршруты редко существуют поодиночке: их удобно группировать. Метод Route::prefix('admin')->group(...) добавляет общий префикс URL ко всем вложенным маршрутам, а Route::middleware('auth')->group(...) навешивает на них общий фильтр. Это убирает повторения и делает карту маршрутов читаемой. Отдельно полезны именованные маршруты: вызов ->name('products.show') даёт маршруту имя, по которому потом генерируют ссылки через хелпер route('products.show', $id). Преимущество в том, что если адрес страницы изменится, достаточно поправить его в одном месте — все ссылки, построенные по имени, обновятся автоматически. Также маршруты поддерживают ограничения параметров через ->where('id', '[0-9]+'), что заставляет роутер принимать, например, только числовые идентификаторы и отбрасывать мусорные URL ещё до контроллера.
Итог: маршруты — это карта приложения, связывающая адреса и HTTP-методы с кодом. Дальше разберём, как переносить логику из замыканий в контроллеры.