Router в EE_FrameWork разбирает URL и превращает его в четыре значения:
ENV_CONTROLLER_PATHENV_CONTROLLER_NAMEENV_CONTROLLER_ACTIONENV_CONTROLLER_ARGS
Маршрут интерпретируется относительно папки app/.
Примеры:
/ -> app/index/index.php -> index()
/admin -> app/admin/index.php -> index()
/admin/pages -> app/admin/index.php -> pages()
/hello -> app/hello/index.php -> index()
/hello/edit/id/15 -> app/hello/index.php -> edit(['id', '15'])
Алгоритм в упрощённом виде:
- Берёт
$_GET['route']. - Нормализует путь.
- Проверяет, является ли первый сегмент папкой внутри
app/. - Если да, ищет контроллер внутри этой папки.
- Если нет, пытается трактовать сегмент как файл-контроллер.
- Если action не существует, но контроллер имеет
index(), Router передаёт action как первый аргумент вindex($params).
Именно поэтому путь вида /docs/quick-start может обрабатываться одним ControllerDocs::index() с аргументом quick-start.
В текущей архитектуре docs-модуль — это обычный маршрут фреймворка:
- контроллер живёт в
app/docs/index.php; - контент живёт в
custom/docs/; - URL
/docs/<slug>должен доходить до Router так же, как и любой другой маршрут проекта.
Практический приоритет такой:
- существующая папка-модуль;
- существующий файл контроллера;
- fallback в
index-контроллер с интерпретацией сегмента как action; error.phpчерезSysClass::handleRedirect(404).
Специального декларативного роутера с отдельной таблицей маршрутов здесь нет.
Маршрут формируется из структуры файлов.
Плюсы:
- низкий порог входа;
- быстрое создание модуля;
- легко понять, откуда берётся путь.
Минусы:
- нужно дисциплинированно держать структуру
app/; - сложные alias-маршруты лучше решать контроллером или hooks;
- очень нетривиальные SEO-схемы требуют отдельного проектного слоя.
Для categories и pages теперь действует отдельный semantic URL layer поверх core-полей slug и optional-полей route_path.
Контракт такой:
- категория:
/<category-slug>/<child-category-slug> - страница:
/<category-slug>/<child-category-slug>/<page-slug>
Правила:
slugхранится в самих таблицахee_categoriesиee_pages, а не в свойствах;route_pathтоже хранится в core-таблицахee_categoriesиee_pages, а не в свойствах;- если у сущности заполнен
route_path, public resolver использует именно его; - если
route_pathпуст, маршрут собирается из обычной slug-иерархии; - Router сначала проверяет реальные модули и контроллеры в
app/, и только потом пробует semantic entity route; - public route резолвится по текущему языковому контексту;
- для явного выбора не-default языка поддерживается suffix-параметр
?sl=EN.
Пример:
/gaspra
/gaspra/gostinica-nika
/noviyafon/catalog/flat
/gaspra/gostinica-nika?sl=EN
Это позволяет держать два режима:
- штатный EE semantic routing по
slug; - опциональное сохранение donor-path при полном переезде с другого движка.
docs в этот контракт не входят и продолжают жить отдельным модулем /docs/....
После резолва semantic entity route Router передаёт запрос в обычный public controller:
app/index/index.php -> ControllerIndex::public_entity()
Дальше уже public model layer собирает domain payload:
ModelPublicCatalog::getCategoryPayload()ModelPublicCatalog::getPagePayload()
И только потом включаются dedicated views:
app/index/views/v_public_category.phpapp/index/views/v_public_page.php
Если на сервере есть защитные deny-регексы для внутренних директорий, они должны быть привязаны к имени директории, а не к любому префиксу пути.
Хороший вариант:
^/(logs|classes|layouts|inc|config)(/|$)
Опасный вариант:
/(logs|classes|layouts|inc|config)
Во втором случае сервер может начать блокировать легальные публичные URL вроде /docs/settings-page, даже если это не внутренний каталог проекта.
Router умеет кэшировать разрешение маршрута.
Что важно знать:
- route cache теперь можно реально выключать;
- backend может быть
fileилиredis; - route cache отделён по namespace/version;
- ключ route cache учитывает языковой контекст semantic public URL;
- для очистки есть отдельные admin actions.
Используйте route cache, когда:
- структура маршрутов стабильна;
- проект работает под нагрузкой;
- у вас нет частой hot-смены модулей без очистки кэша.
Чистите route cache после:
- добавления нового контроллера;
- переименования action;
- изменения структуры
app/; - деплоя, который меняет маршрутизацию.
Для быстрого анализа:
- проверьте, какой URL реально пришёл в веб-сервер;
- очистите route cache;
- откройте
logs/router_error/..., если маршрут падает в error flow; - при необходимости временно смотрите runtime-константы
ENV_CONTROLLER_*через локальную диагностику, а не через публичный контракт документации.
Чеклист:
- Убедитесь, что файл контроллера реально существует.
- Проверьте имя класса:
Controller<ModuleName>. - Проверьте, что action callable.
- Очистите route cache.
- Посмотрите
logs/router_error/....
Если Router не смог найти контроллер или action, штатное поведение должно идти через error.php в корне проекта.