Создание собственного роутера для PHP приложений

Раздел: Веб-разработка на PHP -> Работа с URL в PHP

Основные методы работы с URL

Как организовать разбор URL в PHP для создания ЧПУ?

Наиболее эффективное решение для обработки URL в веб-приложении - создание класса-роутера. Он позволяет сопоставлять шаблоны маршрутов с обработчиками. Пример реализации:

class Router {
    private $routes = [];
    public function add($pattern, $callback) {
        $this->routes[$pattern] = $callback;
    }
    public function match($uri) {
        foreach ($this->routes as $pattern => $callback) {
            if (preg_match($pattern, $uri, $matches)) {
                array_shift($matches);
                return call_user_func_array($callback, $matches);
            }
        }
        return false;
    }
}
// Использование:
$router = new Router();
$router->add('~^/$~', function() { echo 'Главная'; });
$router->add('~^/user/(\d+)$~', function($id) { echo "Пользователь $id"; });
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$router->match($uri);

Php создание ссылки (создание ссылки в php)

Класс хранит массив маршрутов. Метод add принимает регулярное выражение (с разделителем ~) и замыкание. Метод match обходит маршруты, применяет preg_match и при совпадении вызывает обработчик, передавая захваченные группы.

Типичные ошибки и решения:

  • Не учтён базовый путь приложения (если скрипт не в корне домена). Удаляйте префикс с помощью str_replace или константы.
  • Параметры query string (после ?) попадают в URI. Используйте parse_url(..., PHP_URL_PATH) для извлечения пути.
  • Регулярное выражение не соответствует UTF-8. Добавляйте модификатор u.

Вариант 1. Разбиение URI через explode

Вопрос: Как разбить URI на части без регулярных выражений?

$uri = $_SERVER['REQUEST_URI'];
$parts = explode('/', trim($uri, '/'));
$controller = $parts[0] ?? 'index';
$action = $parts[1] ?? 'default';
// Пример: /user/profile -> $controller='user', $action='profile'

Php текущая url (текущая url в php)

Простой способ для небольших проектов. Не учитывает query string и требует дополнительной обработки.

  • Query string (например, ?id=5) остаётся в последнем сегменте. Используйте strtok или parse_url для отделения.
  • Пустой URI даёт массив с пустой строкой после trim. Проверяйте наличие элементов.

Вариант 2. Использование parse_url и parse_str

Вопрос: Как получить компоненты URL и параметры запроса в виде массива?

$url = 'http://example.com/page?name=value&id=5';
$parsed = parse_url($url);
$path = $parsed['path'] ?? '/';
parse_str($parsed['query'] ?? '', $query);
// $query['name'] = 'value'; $query['id'] = '5'

Mobile php url (мобильный url в php)

Функция parse_url разбирает URL на компоненты (схема, хост, путь, query и т.д.). parse_str превращает строку запроса в ассоциативный массив.

  • Если URL не содержит схему (например, /page?q=1), parse_url может интерпретировать его некорректно. Добавляйте префикс http:// при необходимости.
  • Параметры с одинаковыми именами (например, a[]=1&a[]=2) parse_str обрабатывает как массив.

Вариант 3. Прямое применение регулярных выражений

Вопрос: Как задать шаблоны маршрутов с динамическими сегментами?

$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
if (preg_match('~^/user/(\d+)/?$~', $uri, $matches)) {
    $userId = $matches[1];
    // ...
}

Подходит для небольшого числа маршрутов. Каждое условие обрабатывается отдельно.

  • Сложность поддержки при росте количества маршрутов.
  • Проблемы с производительностью при большом количестве проверок - лучше использовать единый роутер.
- Php строка url (строка url в php)
- Url class php (класс url в php)
- Php url query (url-запрос (query string) в php)

Расширенные примеры работы с URL

Роутер с поддержкой HTTP методов

Добавление проверки HTTP метода позволяет точно сопоставлять маршруты.

Пример
class MethodRouter {
    private $routes = [];
    public function add($method, $pattern, $handler) {
        $this->routes[] = ['method' => strtoupper($method), 'pattern' => $pattern, 'handler' => $handler];
    }
    public function dispatch($uri, $method) {
        $uri = parse_url($uri, PHP_URL_PATH);
        foreach ($this->routes as $route) {
            if ($route['method'] !== strtoupper($method)) continue;
            if (preg_match($route['pattern'], $uri, $matches)) {
                array_shift($matches);
                return call_user_func_array($route['handler'], $matches);
            }
        }
        http_response_code(404);
        echo json_encode(['error' => 'Not Found']);
    }
}
// Пример использования:
$router = new MethodRouter();
$router->add('GET', '~^/api/user/(\d+)$~', function($id) {
    echo json_encode(['user_id' => $id]);
});
$router->add('POST', '~^/api/user$~', function() {
    echo json_encode(['status' => 'created']);
});
$router->dispatch($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']);
При GET /api/user/42 ответ: {"user_id":42}
При POST /api/user ответ: {"status":"created"}

Обработка query string с помощью parse_str

Использование parse_str для преобразования строки запроса в массив.

Пример
$queryString = 'name=John&age=30&hobbies[]=reading&hobbies[]=coding';
parse_str($queryString, $result);
print_r($result);
Array
(
    [name] => John
    [age] => 30
    [hobbies] => Array
        (
            [0] => reading
            [1] => coding
        )
)

Редирект на другой URL

Часто требуется перенаправить пользователя на другую страницу.

Пример
// Редирект на новый адрес
header('Location: /new-page');
exit;
// Редирект с параметрами
header('Location: /search?q=' . urlencode($query));
exit;

Важно: функция header должна быть вызвана до любого вывода. После редиректа всегда используйте exit.

Работа с фрагментом (якорь)

Фрагмент (#) не передаётся на сервер, но его можно получить на клиенте. Однако parse_url умеет его извлекать, если он есть в URL.

Пример
$url = 'https://example.com/page#section2';
$fragment = parse_url($url, PHP_URL_FRAGMENT);
echo $fragment; // section2

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

Валидация URL с помощью filter_var

Проверка корректности URL перед обработкой.

Пример
$url = 'https://example.com';
if (filter_var($url, FILTER_VALIDATE_URL)) {
    echo 'URL корректен';
} else {
    echo 'Некорректный URL';
}
URL корректен

Построение URL из компонентов

Для создания URL с параметрами удобно использовать http_build_query.

Пример
$base = '/search';
$params = ['q' => 'php', 'page' => 2];
$url = $base . '?' . http_build_query($params);
echo $url;
/search?q=php&page=2

Движок URL в PHP - comments

En
Engine php url (php)