Создание маршрутизатора в собственном фреймворке на PHP. Часть 2

Andre Kowalsy
111 раз
5 мин чтения
Опубликовано: 23-07-2025
Обновлено: 25-03-2026
Категории: Пишем свою CMS

В этом посте мы продолжаем работу над одним из ключевых классов нашего фреймворка — классом маршрутизатора. На предыдущем этапе мы описали правила маршрутов и добавили их в таблицу маршрутов. Давайте подробнее рассмотрим, как мы будем обрабатывать запросы с помощью методов, которые мы создадим в нашем маршрутизаторе.

Обработка запроса: метод dispatch

Одним из основных методов нашего маршрутизатора будет dispatch, который будет принимать строку запроса. Важным дополнением к этому методу станет метод matchRoute, выполняющий проверку соответствия запроса с заданными маршрутами.

Метод matchRoute

Метод matchRoute будет статичным и принимать один аргумент — строку запроса. Он будет возвращать булево значение — true, если маршрут найден, и false, если соответствия нет. Начнем с его реализации.

protected static function matchRoute($request) {
    // Для упрощения возвращаем true
    return true;
}

Этот метод будет вызван из dispatch. Мы сможем проверять, существует ли запрашиваемый маршрут, и, соответственно, обрабатывать его. В качестве начального теста можно оставить возвращаемое значение true, чтобы убедиться, что метод вызывается корректно.

Цикл по маршрутам

В методе matchRoute нам понадобится проходить по нашей таблице маршрутов, которая хранится в свойстве roots. Используя цикл, мы будем проверять каждое регулярное выражение:

foreach (self::roots as $pattern => $route) {
    // TODO: Проверка соответствия маршрута
}

В каждой итерации мы будем использовать функцию preg_match, чтобы проверить, соответствует ли запрос текущему шаблону маршрута. Задаем нужные параметры, включая флаги для удобства обработки.

Обработка результатов

Если маршрут совпадает, мы сохраним найденные данные для дальнейшей обработки. Возвращаем true или false в зависимости от результата проверки. Также важно хранить информацию о контроллере и действии, которые необходимо вызвать:

if (preg_match($pattern, $request, $matches)) {
    // Сохраняем соответствующий контроллер и экшен
    // Пример: $matches['controller'] = "Main", $matches['action'] = "index"
    return true;
}
Подробное извлечение маршрута

Теперь давайте рассмотрим, как извлекать конкретные параметры маршрутов, такие как контроллер и экшен. В случае успешного сопоставления мы можем проходить по массиву совпадений и отбирать только именованные ключи, которые представляют собой контроллер и экшен.

foreach ($matches as $key => $value) {
    if (is_string($key)) {
        self::$root[$key] = $value; // Сохраняем в маршруте
    }
}
Установка значений по умолчанию

Контроллер и экшен могут быть не заданы в URL. В этом случае важно назначить значения по умолчанию, чтобы избежать ошибок. Например, если экшен не указан, мы можем установить его значение как index.

if (empty(self::$root['action'])) {
    self::$root['action'] = 'index';
}
Префикс админки

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

if (empty(self::$root['admin_prefix'])) {
    self::$root['admin_prefix'] = '';
} else {
    self::$root['admin_prefix'] .= '/';
}
Конвенции именования

Не забывайте, что в программировании существуют общепринятые конвенции именования. Например, классы следует называть с использованием CamelCase, то есть каждое слово в имени начинается с заглавной буквы. Методы, в свою очередь, именуются в lowerCamelCase, где первое слово с маленькой буквы. Это поможет поддерживать читаемость вашего кода.

Создание функций для преобразования имен

Добавьте методы для преобразования имен контроллеров и экшенов:

protected static function upperCamelCase($name) {
    // Преобразование имени в UpperCamelCase
}

protected static function lowerCamelCase($name) {
    // Преобразование имени в lowerCamelCase
}

В этих методах используйте функции str_replace и ucwords, чтобы преобразовать имена в нужный вам формат.

Заключение

В завершение текущего урока мы подготовили основные функции маршрутизатора. Теперь наш маршрутизатор готов к использованию. В следующих уроках мы сосредоточимся на создании и вызове контроллеров и их действий, чтобы обработать запросы, поступающие от пользователей. Этот этап завершит формирование внутренней логики нашего фреймворка и позволит нам реализовывать более сложные функции.