🧭 Роутинг
Маршруты (routes) определяют, какой код должен выполняться при обращении к определённому URL на вашем сайте.
Пример: если пользователь переходит по адресу /about, вы можете задать маршрут, который покажет страницу «О нас».
🔰 Базовый пример
Для задания маршрутов в PageBlocks используется фасад Route:
use Boshnik\PageBlocks\Facades\Route;
Route::get('/about', function () {
return 'Это страница О нас';
});📥 Когда кто-то открывает https://example.com/about, эта функция выполняется, и пользователь видит её результат.
Из маршрута можно вернуть:
| Тип | Результат |
|---|---|
string | Обычный текст |
array | JSON |
object | JSON или HTML (в зависимости от содержимого и заголовков) |
Response | Явный объект ответа через класс Response |
Всё, что вы возвращаете из маршрута, автоматически проходит через
Response::dispatchResponse, который определяет, как правильно отдать результат клиенту.
📂 Где находятся маршруты?
Все маршруты хранятся в папке core/App/routes вашего проекта:
core/
└── App/
└── routes/
├── web.php
├── api.php
└── ...🔄 Все .php-файлы в этой папке автоматически подгружаются системой и регистрируют свои маршруты при старте приложения.
📝 Вы можете разбивать маршруты на любое количество файлов:
web.php— маршруты основного сайтаapi.php— маршруты APIadmin.php,auth.php,blog.php— любые дополнительные наборы
Название файла не имеет значения. Главное — чтобы он лежал в
core/App/routesи имел расширение.php.
⚙️ Методы маршрутов
Каждый маршрут связан с HTTP-методом — это способ, которым браузер или клиент отправляет запрос на сервер. Вот основные методы:
📄 Route::get($uri, $callback)
Отвечает на GET-запросы — когда пользователь просто открывает страницу.
Route::get('/contact', function () {
return 'Контактная информация';
});📩 Route::post($uri, $callback)
Обрабатывает POST-запросы — чаще всего используются при отправке форм.
Route::post('/feedback', function () {
return 'Спасибо за отзыв!';
});📝 Route::put($uri, $callback)
Используется для обновления ресурса целиком.
Route::put('/profile', function () {
return 'Профиль обновлён';
});🔧 Route::patch($uri, $callback)
Частичное обновление ресурса — например, изменение одного поля.
Route::patch('/profile/email', function () {
return 'Email обновлён';
});🗑 Route::delete($uri, $callback)
Удаление ресурса.
Route::delete('/account', function () {
return 'Аккаунт удалён';
});⚙️ Route::options($uri, $callback)
Обрабатывает OPTIONS-запросы — полезно для CORS и API.
Route::options('/api/data', function () {
return response('', 204)
->header('Allow', 'GET, POST, OPTIONS')
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
->header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
});🔀 Route::match(array $methods, string $uri, $callback)
Позволяет задать маршрут, который будет срабатывать на несколько методов. Например, если один и тот же URL должен обрабатывать и GET, и POST:
Route::match(['GET', 'POST'], '/subscribe', function () {
return 'Форма подписки или её обработка';
});👆 Такой маршрут сработает:
- при открытии
/subscribeв браузере (GET); - при отправке формы на этот же адрес (POST).
Методы должны указываться в верхнем регистре (GET, POST, PUT, и т.д.).
🧮 Route::any(string $uri, $callback)
Срабатывает на все типы HTTP-запросов: GET, POST, PUT, DELETE, PATCH, OPTIONS.
Route::any('/ping', function () {
return 'pong';
});Этот маршрут отработает независимо от того, какой метод использует клиент — удобно, если неважно, как пришёл запрос.
🔁 Маршруты перенаправления
Иногда вместо обработки запроса нужно просто перенаправить пользователя на другой URL. Для этого используется метод redirect.
🔁 Route::redirect($from, $to, $status = 302)
Route::redirect('/old-link', '/new-link');👆 Любой, кто откроет /old-link, будет автоматически перенаправлен на /new-link.
По умолчанию используется код 302 (временное перенаправление), но можно указать другой:
Route::redirect('/moved', '/here', 301); // постоянный редирект📦 Полезно при реорганизации сайта или переименовании URL.
🖼 Быстрый маршрут для отображения шаблона
Если нужно просто отобразить шаблон без логики — используйте метод Route::view.
🖼 Route::view($uri, $view, $data = [])
Route::view('/about', 'pages/about');👆 Этот маршрут отобразит шаблон pages/about.tpl.
Можно также передать данные:
Route::view('/thanks', 'pages/thanks', ['title' => 'Спасибо за заказ']);Внутри метод вызывает
response()->view(...), поэтому результат полностью идентичен ручному возврату шаблона.
🧩 Параметры маршрутов
Маршруты могут содержать переменные — параметры, которые автоматически извлекаются из URL и передаются в обработчик.
🎯 Обязательные параметры
Route::get('/user/{id}', function ($id) {
return "Профиль пользователя #$id";
});👆 При переходе на /user/42 будет выведено: Профиль пользователя #42.
❔ Необязательные параметры
Чтобы сделать параметр необязательным, добавьте ? и укажите значение по умолчанию:
Route::get('/user/{name?}', function ($name = 'Гость') {
return "Привет, $name!";
});📥 /user → Привет, Гость! 📥 /user/Анна → Привет, Анна!
🔍 Ограничения параметров — where()
Позволяет задать регулярные выражения для проверки параметров:
Route::get('/user/{id}', function ($id) {
return "Пользователь #$id";
})->where('id', '\\d+');👆 Теперь /user/abc не сработает — только цифры (\d+).
Ограничения можно задать сразу для нескольких параметров:
Route::get('/post/{slug}/{id}', function ($slug, $id) {
return "$slug: $id";
})->where([
'slug' => '[a-z\-]+',
'id' => '\\d+',
]);📦 Доступ к Request внутри маршрута
Чтобы получить доступ к данным запроса, используйте внедрение Request:
use Boshnik\PageBlocks\Http\Request;
Route::post('/submit', function (Request $request) {
$email = $request->input('email');
return "Вы ввели: $email";
});🧃 Именованные маршруты
Именованные маршруты удобны для генерации ссылок и редиректов:
Route::get('/profile/{id}', function ($id) {
return "Профиль #$id";
})->name('profile.show');Теперь вы можете получить ссылку на этот маршрут:
route('profile.show', ['id' => 7]); // /profile/7🧭 Это особенно полезно при генерации ссылок в шаблонах и при использовании редиректов:
response()->redirect(route('profile.show', ['id' => $user->id]));📦 Группы маршрутов
Метод group() позволяет сгруппировать маршруты и применить к ним общие настройки: префикс, middleware, контроллер и т.д.
🔹 Простой пример
Route::group(function () {
Route::get('/a', fn() => 'A');
Route::get('/b', fn() => 'B');
});Маршруты внутри группы будут зарегистрированы как обычно — без префикса или доп. параметров.
🏁 Префикс
Добавляет общий префикс ко всем маршрутам внутри группы:
Route::prefix('/admin')->group(function () {
Route::get('/dashboard', fn() => 'Панель');
Route::get('/users', fn() => 'Пользователи');
});📥 Зарегистрируются маршруты:
/admin/dashboard/admin/users
🛡 С общим middleware
Route::middleware('auth')->group(function () {
Route::get('/cabinet', fn() => 'Личный кабинет');
});Все маршруты внутри группы будут обрабатываться через middleware auth.
👨🏫 Контроллер по умолчанию
Позволяет задать общий контроллер для маршрутов внутри группы:
Route::controller(ProfileController::class)->group(function () {
Route::get('/edit', 'edit');
Route::post('/update', 'update');
});🔁 Вызовутся методы:
ProfileController->edit()ProfileController->update()
🛡 Middleware
Middleware — это промежуточные обработчики, которые выполняются до запуска контроллера или замыкания. Например, проверка авторизации, CSRF и т.п.
📌 Пример использования
Route::get('/dashboard', fn() => 'Панель')->middleware('auth');🧩 Несколько middleware
Route::middleware(['auth', 'admin'])->group(function () {
Route::get('/admin', fn() => 'Admin');
});🚫 Исключение middleware
Можно отключить middleware, применённый ранее:
Route::get('/open', fn() => 'Открыто')->withoutMiddleware('auth');🧾 Где настраиваются алиасы?
Middleware можно задавать как имена (алиасы), так и полные классы. Алиасы настраиваются в app.php:
'middleware' => [
'auth' => \App\Middleware\Auth::class,
],🛑 Fallback-маршруты
Если ни один маршрут не подошёл, можно определить запасной (fallback) маршрут, который выполнится в последнюю очередь.
🚨 Route::fallback($callback)
Route::fallback(function () {
return response()->view('errors/404')->send();
});📌 Такой маршрут срабатывает только если никакой другой не совпал.
✅ Подходит для кастомных страниц 404 или других глобальных обработчиков.
Обязательно указывайте fallback в конце всех маршрутов, иначе он может "перехватить" другие.
🔐 CSRF-защита
Все маршруты с методами POST, PUT, PATCH, DELETE автоматически защищаются от CSRF-атак.
Чтобы пройти проверку, форма должна содержать скрытое поле с токеном.
✅ Способ 1: {csrf()}
В шаблоне можно использовать удобную функцию:
<form method="POST">
{csrf()}
<button>Отправить</button>
</form>Она сгенерирует:
<input type="hidden" name="_token" value="{csrf_token}">Также поддерживает spoofing, если вручную добавить _method:
<form method="POST">
{csrf()}
<input type="hidden" name="_method" value="PUT">
<button>Обновить</button>
</form>🛠 Способ 2: вручную вставить токен
Можно самостоятельно вставить скрытое поле:
<input type="hidden" name="_token" value="{csrf_token}">Это полезно, если вы хотите иметь полный контроль над HTML.
⚙️ Способ 3: meta-тег с токеном
Если вы используете pbFetch, он автоматически ищет CSRF-токен в meta-теге:
<meta name="csrf-token" content="{csrf_token}">Затем pbFetch сам подставит этот токен в заголовок X-CSRF-TOKEN при отправке запроса.
🔐 Проверку токена выполняет middleware VerifyCsrfToken, который автоматически применяется ко всем маршрутам с методами POST, PUT, PATCH, DELETE.
Если токен отсутствует или неверен — будет показана ошибка 419 Page Expired.