Як працюють маршрутизатори в PHP від arifhossen.dev
Ви втомилися створювати окремі PHP файли для кожної сторінки вашого сайту? Хочете побудувати чисту та професійну систему маршрутизації, як у Laravel або Symfony, але без складнощів повного фреймворку? У цьому посібнику я покажу вам, як створити простий, але потужний маршрутизатор PHP з нуля.
Зміст
- Що таке маршрутизатор і навіщо він вам потрібен?
- Налаштування структури проекту
- Створення класу маршрутизатора
- Створення контролерів
- Обробка різних HTTP методів
- Додавання динамічних маршрутів
- Реалізація в реальному світі
- Кращі практики та безпекові рекомендації
Що таке маршрутизатор і навіщо він вам потрібен?
Уявіть, що ви керуєте рухом у переповненому місті. Саме це робить маршрутизатор для вашого веб-застосунку — він приймає вхідні запити (URL) і направляє їх до правильного місця призначення (коду). Замість того, щоб мати кілька PHP файлів, таких як about.php
, contact.php
та products.php
, ви можете обробляти все через одну точку входу.
Переваги використання маршрутизатора:
- Чисті, SEO-дружні URL
- Краща безпека
- Легше обслуговування
- Професійна структура коду
- Покращена масштабованість
Налаштування структури проекту
Спочатку давайте створимо професійну структуру проекту:
my-project/
├── public/
│ ├── index.php
│ └── .htaccess
├── src/
│ ├── Router.php
│ └── Controllers/
│ ├── HomeController.php
│ └── UserController.php
└── views/
└── home.php
Створіть файл .htaccess
у вашій публічній директорії:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Створення класу маршрутизатора
Ось наш простий, але потужний клас маршрутизатора:
routes['GET'][$path] = $callback;
}
public function post(string $path, callable|array $callback): void
{
$this->routes['POST'][$path] = $callback;
}
public function resolve(): mixed
{
$method = $_SERVER['REQUEST_METHOD'];
$path = $_SERVER['REQUEST_URI'] ?? '/';
$path = explode('?', $path)[0];
$callback = $this->routes[$method][$path] ?? null;
if ($callback === null) {
http_response_code(404);
return "404 Not Found";
}
if (is_array($callback)) {
[$class, $method] = $callback;
$controller = new $class();
return $controller->$method();
}
return $callback();
}
}
Налаштування точки входу
Створіть ваш public/index.php
:
'/../vendor/autoload.php';
use App\Router;
use App\Controllers\HomeController;
use App\Controllers\UserController;
$router = new Router();
// Визначаємо маршрути
$router->get('/', [HomeController::class, 'index']);
$router->get('/about', [HomeController::class, 'about']);
$router->get('/users', [UserController::class, 'index']);
// Обробляємо поточний запит
echo $router->resolve();
```
Створення контролерів
Давайте створимо простий контролер:
[^/]+)', $path);
$pattern = "#^$pattern$#";
$this->routes[$method][$pattern] = $callback;
}
public function resolve(): mixed
{
$method = $_SERVER['REQUEST_METHOD'];
$path = $_SERVER['REQUEST_URI'] ?? '/';
$path = explode('?', $path)[0];
foreach ($this->routes[$method] ?? [] as $pattern => $callback) {
if (preg_match($pattern, $path, $matches)) {
$params = array_filter(
$matches,
fn($key) => !is_numeric($key),
ARRAY_FILTER_USE_KEY
);
if (is_array($callback)) {
[$class, $method] = $callback;
$controller = new $class();
return $controller->$method($params);
}
return $callback($params);
}
}
http_response_code(404);
return "404 Не знайдено";
}
Реалізація в реальному світі
Ось як використовувати динамічні маршрути на практиці:
get('/user/{id}', [UserController::class, 'show']);
$router->get('/blog/{slug}', [BlogController::class, 'show']);
// UserController.php
class UserController
{
public function show(array $params): string
{
$userId = $params['id'];
return "Показати профіль користувача для ID: {$userId}";
}
}
Кращі практики та безпекові рекомендації
1. Валідація вводу
Завжди перевіряйте та очищайте параметри URL:
public function show(array $params): string
{
$userId = filter_var($params['id'], FILTER_VALIDATE_INT);
if ($userId === false) {
return "Невірний ID користувача";
}
return "Показати профіль користувача для ID: {$userId}";
}
2. Обробка помилок
Реалізуйте правильну обробку помилок:
try {
return $router->resolve();
} catch (Exception $e) {
http_response_code(500);
return "Внутрішня помилка сервера: " . $e->getMessage();
}
3. Безпекові заголовки
Додайте безпекові заголовки в точці входу:
header("X-Content-Type-Options: nosniff");
header("X-Frame-Options: DENY");
header("X-XSS-Protection: 1; mode=block");
Висновок
Створення власного маршрутизатора PHP — це чудовий спосіб зрозуміти, як працюють сучасні фреймворки "під капотом". Цей простий маршрутизатор надає солідну основу, на якій ви можете будувати ваш проект, зважаючи на його потреби.
Пам'ятайте, хоча цей маршрутизатор чудово підходить для навчання та малих проектів, для виробничих застосунків вам, ймовірно, слід звернутися до використання перевірених бібліотек маршрутизації або фреймворків, які надають додаткові можливості та заходи безпеки.
Наступні кроки
- Додати підтримку проміжного програмного забезпечення
- Реалізувати групи маршрутів
- Додати іменовані маршрути
- Реалізувати кешування для кращої продуктивності
Ви вже створювали власний маршрутизатор? Які функції ви б додали до цієї базової реалізації? Поділіться своїми думками в коментарях!
Перекладено з: How to Build a Simple PHP Router Without a Framework: A Beginner’s Guide