Когда пользователь запрашивает какую-либо страницу нашего сайта (напр. кликая на ссылку, которая ведет на одна из страниц сайта), сервер получается адрес запроса и делает его доступным интерпретару PHP.
Таким образом, php-приложению требуется понять, какие именно действия необходимо сделать в ответ на конкретный запрос. Процесс выбора этих конкретных действий и есть процесс марутизации запроса пользователя.
Для того, чтобы дальнейшие рассуждения были понятны, введем понятние маршрута.
Маршрут -- уникальная строка, которая соответствует действию контроллера.
Один маршрут должен соответствовать одному действию одного контроллера, т.е. является уникальным (иначе Ядро системы не сможет понять какие именно действия выполнять).
Также можно сказать, что маршрут - это адрес действия в списке действий, которые умеет выполнять наша система.
Далее рассмотрим подробнее как именно система понимает какой именно контроллер (и какое его действие) соответствует данному маршруту.
Маршрут (строка маршрута) - внутренее понятие фреймворка (в данном случае SMVC
),
по сути это абстракция - некая строка, которая обозначает адрес действия.
Но откуда её взять в реальной жизни?
Ответ такой: маршрут может получаться из данных адреса запроса клиента, направленного серверу.
Таким образом, логически система выполняет действия в таком порядке:
- Анализ HTTP
Запроса
клиента. - Получение
строки маршрута
изЗапроса
(ниже посмотрим как это происходит вsmvc
, получать строку маршрута можно разными способами, такой подход делает систему более гибкой) - Получение и вызов
действия контроллера
, соответствующегомаршруту
.
Кратко описать процесс работы фреймворка можно так:
- У Приложения есть единственный файл (т.н. "точка входа" в нашем случае это файл web/index.php), с которого начинается обработка любого запроса пришедшего от клиента (см. подробнее о Клиент-Серверной архитектуре). Т.е. это означается что все скрипты нашего сайта начинают работать именно с этого файла.
- В точке входа Приложение получается экземпляр класса
\ItForFree\SimpleMVC\Application
(см. реализацию - отвечает за работу ядра в целом, подключая по мере необходимости другие части ярда), устанавливает ему конфигурацию (через слияние основного и локального файлов конфигурации) и запускает функционал Ядра, вызвав методrun()
:
\ItForFree\SimpleMVC\Application::get()
->setConfiguration($config)
->run();
- Вызов метода
run()
фактически запускает функционал ядра, который, анализируя текущее состояние адреса страницы (URL), принимает решение о том, какой контроллер отвечает за данный адрес и какое именно действие котроллера должно быть вызвано. Далее фрагмент кода из методаrun()
:
// .....
$route = $this->getConfigObject('core.router.class')::getRoute();
/**
* @var \ItForFree\SimpleMVC\Router\WebRouter
*/
$Router = $this->getConfigObject('core.router.class');
$Router->callControllerAction($route); // определяем и вызываем нужно действие контроллера
// .....
-- как видим за процесс определения имени контроллера, имени действий и их вызов происходят в методе callControllerAction()
, реализованном уже другой классе Ядра, а именно \ItForFree\SimpleMVC\Router\WebRouter
(исх. код).
При этом код:
$route = $this->getConfigObject('core.router.class')::getRoute();
-- отвечает за получение строки маршрута
, для чего статический вызывается метод getRoute()
класса, лежащего в кофиге приложения по адресу core.router.class - подразумевается, что этот метод этого класса отвечает за реализацию процесса получения строки маршрута.
Ещё раз схема работы, но теперь кратко
Таким, образом можно сказать, что взаимодействие Приложения и Ядра в части маршрутизации проходят по цепочке в таком порядке (по времени работы кода Приложения или Ядра):
Приложение
(запускает функционал ядра черезApplliction->run()
в своей точке входа)Ядро
(используя свои классы определяет контроллер и действие, соответствующие маршруту (url) создает экземпляр контроллера и вызывает на нем метод)Приложение
(выполняется код действий контроллера, и все что это действие вызовет)
Маршрут из адреса запроса может извлекаться разными способами - это зависит от внутренней логики бэкэнд-приложения.
Например, есть адрес:
http://example.loc/user/list
Для Приложения интерес здесь предствляет та часть URL, что идет после доменного имени - в данном случае это user/list
, ведь именно её можно ассоциировать в логике системы с каким-нибудь дейтсвием (в данном случае логично напрашивается вывод списка пользователей).
Рассмотрим пример маршрута из Приложения SimpleMVC-example, авторизуемся под админом (его учетная запись есть в дампе стартовой БД) и перейдем на страницу списка пользователей, тогда в адресной строке браузера мы увидим адрес вроде:
http://smvc.loc/index.php?route=admin/adminusers/index
Здесь значением маршрута для движка (в нашем случае - Ядра SimplrMVC) будет являтся значение GET-параметра route
в данном случае это значение равно admin/adminusers/index
Как уже говорилось выше, за сопоставление отвечает \ItForFree\SimpleMVC\Router\WebRouter
-- изучите работу его метода callControllerAction()
, этот метод получает на вход строку машрута и далее пытается по ней (используя собственную логику) определить:
- имя класса контроллера
- имя действия контроллера (т.е. фактически имя метода контроллера)
Если оба пунта удается выполнить - то создается объект класса контроллера и вызывается его действие, т.е. в дело вступает код, написанный программистом, использующим SMVC