Маршрутизация (Routing)

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

Простейшие маршруты принимают URI и замыкание, обеспечивания простые и понятные способы определения маршрутов без лишних усложнений.

use Imhotep\Facades\Route;

Route::get('/welcome', function () {
    return "Hello World!";
});

Основные маршрутные файлы

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

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

Маршрутизатор позволяет зарегистрировать маршруты, для основных 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'], $uri, $callback);
Route::any($uri, $callback);

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

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

Вы можете внедрить необходимые зависимости в callback функцию маршрута. Все объявленные зависимости будут автоматически извлечены из контейнера Imhotep. Например, если вам необходимо получить доступ к текущему запросу, внедрите класс Imhotep\Http\Request:

use Imhotep\Http\Request;

Route::get('/me', function (Request $request) {
    // ...
});

Переадресация

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

Route::redirect('/from', '/to');

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

Route::redirect('/from', '/to', 301);

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

View маршруты

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

Route::view('/welcome', 'welcome');

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

Параметры маршрутизации

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

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

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

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

Route::get('/user/{user_id}/posts/{post_id}', function ($user_id, $post_id) {
    // ...
});

Параметры маршрута всегда заключены в фигурные скобки {}, и могут состоять из символов латинского алфавита и знака подчеркивания _. Параметры маршрута будут автоматически внедрены в callback в порядке их объявлений.

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

Если в маршрут необходимо внедрить зависимости в callback функцию маршрута, укажите эти зависимости перед параметрами маршрута:

use Imhotep\Http\Request;

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

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

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

use Imhotep\Http\Request;

Route::get('/docs/{page?}', function ($page = 'index') {
    return $page;
});

Проверка регулярными выражениями

Вы можете ограничить формат параметров маршрута используя метод where экземпляра Route. Данный метод принимает имя параметра и регулярное выражение для проверки параметра.

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

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

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

Route::get('/user/{id}', function ($id) {
    // ...
})->whereNumber('id');

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

Route::get('/user/{uuid}', function ($id) {
    // ...
})->whereUuid('name');

Route::get('/category/{category}', function ($id) {
    // ...
})->whereIn('category', ['auto', 'work', 'hobby']);

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

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

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

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

Route::get('/user/{id}', function ($id) {
    // Будет выполнен, если {id} состоит из цифр
});

Кодирование обратных слэшей

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

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

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

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

Именованные маршруты позволяют легко сформировать URL-адреса или переадресации. Используя метод name, можно связать маршрут с уникальным именем.

Route::get('/user/settings', $callback)->name('settings');

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

Создание URL-адресов для именованных маршрутов

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

// Generating URL
$url = route('settings');

// Generating redirect
return redirect()->route('settings');

return to_route('settings');

Если маршруты содержат параметры, передайте их вторым аргументом в функции route. Переданные параметры будут автоматически вставлены в сформированный URL в правильное место.

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

$url = route('profile', ['id' => 1]);

// Generating: /user/1/profile

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

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

$url = route('profile', ['id' => 1, 'images' => 'yes']);

// Generating: /user/1/profile?images=yes

Проверка текущего маршрута

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

class MyMiddleware
{
    public function handle($request, Closure $next)
    {
        if ($request->route()->named('profile')) {
            // ...
        }
     
        return $next($request);
    }
}

Группировка маршрутов

Группировка маршрутов позволяет задать общие атрибуты маршрута, такие как middleware, controller, prefix и т.д., без необходимости указания их для каждого маршрута отдельно.

Вложенные группы поддерживают "объединения" атрибутов со своей родительской группой. Middleware и условия объединяются, а имена и префиксы добавляются.

Middleware

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

Route::middleware(['first', 'second'])->group(function () {
    Route::get('/', function () {
        // Uses first & second middleware
    });
 
    Route::get('/user/profile', function () {
        // Uses first & second middleware
    });
});

Контроллеры

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

use App\Http\Controllers\ProductController;

Route::controller(ProductController::class)->group(function () {
    Route::get('/products', 'show');
    Route::post('/products', 'store');
});

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

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

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

Регистрацию маршрутов для поддоменов необходимо делать перед, регистрацией маршрутов корневого домен.

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

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

Route::prefix('admin')->group(function () {
    Route::get('/users', function () {
        // Matches the "/admin/users" URL
    });
    
    Route::get('/news', function () {
        // Matches the "/admin/news" URL
    });
});

Префиксы имен

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

Route::name('admin.')->group(function () {
    Route::get('/users', function () {
        // Route assigned name "admin.users"
    })->name('users');
    
    Route::get('/news', function () {
        // Route assigned name "admin.news"
    })->name('news');
});

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

С помощью команды route:list, можно просмотреть список всех зарегистрированных маршрутов в приложении:

php imhotep route:list

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

Когда приложение выложено в продакшене, воспользуйтесь кешированием маршрутов. Это значительно ускорит регистрацию маршрутов в приложении. Для создания кеша, выполните команду route:cache:

php imhotep route:cache

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

Для удаления кеша маршрутов, используйте команду route:clear:

php imhotep route:clear