Урок 03

Параметры роутов

Что такое параметр

Параметр — переменная часть URL. Передаёт данные в обработчик.

Пример:

/users/5          → {id} = '5'
/posts/hello      → {slug} = 'hello'
/users/5/posts/3  → {userId}=5, {postId}=3

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

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

{id} — параметр. Доступ через аргумент.

/user/42 → $id = '42' (строка!).

Несколько параметров

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

⚠️ Порядок параметров в URL = порядок аргументов.

Ошибка:

Route::get('/posts/{post}/comments/{comment}', function ($comment, $post) {
    // перепутано
});

Имена параметров

По имени, не по порядку.

Route::get('/users/{userId}/posts/{postId}', function ($userId, $postId) {
    // работает, даже если порядок аргументов другой
});

Laravel подставляет по имени.

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

{name?} — с ?.

Route::get('/user/{name?}', function (string $name = 'Guest') {
    return "Hello, {$name}";
});

⚠️ Обязательно значение по умолчанию.

Что работает:

  • /user → $name = 'Guest'.
  • /user/Иван → $name = 'Иван'.

Ограничения — where

Регулярное выражение для параметра:

Route::get('/user/{id}', function ($id) {
    return $id;
})->where('id', '[0-9]+');

Если URL не соответствует — 404.

/user/42 → ok. /user/abc → 404.

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

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

Хелперы для where

whereNumber:

->whereNumber('id')

whereAlpha:

->whereAlpha('slug')

whereAlphaNumeric:

->whereAlphaNumeric('code')

whereUuid:

->whereUuid('uuid')

whereUlid:

->whereUlid('ulid')

whereIn:

->whereIn('type', ['article', 'video', 'podcast'])

⚠️ whereIn не работает с {} — параметр должен быть без скобок для простого случая, но с {} тоже работает.

Глобальные паттерны

Один паттерн на всё:

// AppServiceProvider::boot()
use Illuminate\Support\Facades\Route;

public function boot(): void
{
    Route::pattern('id', '[0-9]+');
}

Теперь все {id} — только цифры.

Несколько:

Route::patterns([
    'id' => '[0-9]+',
    'slug' => '[a-z-]+',
]);

⚠️ Не злоупотребляй — может путать.

Дефолтные значения

Когда параметра нет (для ?):

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

$name = 'Guest' — дефолт.

Параметр в контроллере

Route::get('/posts/{id}', [PostController::class, 'show']);

// Контроллер
public function show(string $id)
{
    return Post::findOrFail($id);
}

Имя аргумента = имя параметра.

Порядок — тоже важен.

Route Model Binding

Если в контроллере указан тип модели — Laravel сам найдёт:

Route::get('/posts/{post}', [PostController::class, 'show']);

public function show(Post $post)
{
    return $post;   // уже модель
}

Что происходит:

  1. Laravel видит {post} и Post $post.
  2. Ищет Post::findOrFail($id).
  3. Передаёт модель.

Если не найдено — 404.

Подробнее — урок 7.

Значения по умолчанию в контроллере

public function show(string $id = 'default') { }

Работает с ?.

Динамические префиксы

Route::get('/{lang}/posts', function ($lang) {
    app()->setLocale($lang);
    return Post::all();
});

/ru/posts, /en/posts — разные языки.

Практика: блог

// routes/web.php

Route::get('/blog/{category}/{slug}', function ($category, $slug) {
    return "Category: {$category}, Post: {$slug}";
})->where([
    'category' => '[a-z-]+',
    'slug' => '[a-z0-9-]+',
]);

Route::get('/users/{id}/posts/{postId}', function ($id, $postId) {
    return "User {$id}, Post {$postId}";
})->whereNumber('id')->whereNumber('postId');

Проверь через route:list и curl.

Частые ошибки

1. Забыли ? для необязательного:

Route::get('/user/{name}', function ($name = 'Guest') { });
// /user → 404

// Правильно:
Route::get('/user/{name?}', ...)

2. Забыли значение по умолчанию:

Route::get('/user/{name?}', function ($name) { });
// Error: Missing argument

3. Путаница в порядке:

Route::get('/{a}/{b}', function ($b, $a) { });
// Laravel подставит по имени — работает, но запутанно

4. whereIn без {}:

->whereIn('type', ['a', 'b'])
// Работает, если параметр один

5. Слишком строгие регулярки:

->where('slug', '[a-z]+')
// /post-1 не сработает (есть цифры и дефис)

Итог

  • {id} — обязательный.
  • {id?} — необязательный (с дефолтом).
  • Имена совпадают с аргументами.
  • where — регулярка.
  • whereNumber, whereUuid — хелперы.
  • Route::pattern — глобально.
  • Route Model Binding — автоматический поиск.
  • Правило: ограничивай параметры — меньше ошибок.

Дальше — именованные роуты.