Я разработал базовую структуру MVC как учебный проект в php – на самом деле это вторая версия, и я пытаюсь улучшить два аспекта, которые первая версия не оправдала:
Я могу взять запрос и разобрать его на различные части, например, контроллер, действие, аргументы и т. Д. Они сопоставляются с соответствующими классами / файлами контроллера, например «/ foo / bar» -> FooController :: bar () – все это сделано в моем классе RequestRouter и инкапсулировано в объект Request.
Controller :: methods () отлично отображает правильные представления.
Затем идут модули, которые организованы так, как ядро структурировано (/ root / raspberry / vendors / core / module)
Проблема, на мой взгляд, в настоящий момент связана с комбинацией обработки маршрутизации / запроса, в которой находятся модули:
После некоторых исследований, я полагаю, я мог бы создать Decorator , который реализует шаблон Front Controller и обертывает данный контроллер. Декоратор может повторно разбить запрос на создание / редактирование контроллера и повторную карту оставшихся сегментов (/ editor / action / args).
Все это похоже на то, что это может работать нормально, но я чувствую, что мне не хватает чего-то фундаментального ранее в потоке (RequestRouter). Я исследую другие подобные вопросы здесь, в SO, и читаю на HMVC, и в принципе кажется, что он может ответить на мои вопросы, но он кажется более ориентированным на интерфейс, чем с каркасом (если это имеет смысл?) также посмотрел на другие структуры, такие как Kohana, но я не совсем понимаю, как их модульная система и маршрутизация на несколько контроллеров в одном модуле работают.
Любые идеи или предложения по эффективному внедрению модульной системы без введения Front Controller или повторного анализа запроса были бы высоко оценены. В качестве альтернативы, если я должен переструктурировать свои модули по-другому, я хотел бы понять, как это сделать.
Мой RequestRouter поддерживает список маршрутов, которые я предварительно определил (включая их методы по умолчанию). Используя эти заранее определенные маршруты, я могу получить доступ / admin / editor и получить EditorController :: index (), но мне нужно будет определить маршрут для каждого контроллера и запрос, который поступает на контроллеры в модуле. Я не думаю, что это хороший дизайн. Вот пример моих маршрутов:
Array ( [/foo] => Array ( [controller] => FooController [method] => bar [path] => /core ) [/admin] => Array ( [controller] => AdminController [method] => index [path] => /vendors/admin ) [/admin/editor] => Array ( [controller] => EditorController [method] => index [path] => /vendors/admin ) )
Это объект моего запроса выглядит так:
Request Object ( [properties:Request:private] => Array ( [url] => /admin/editor [query] => [uri] => /admin/editor [controller] => admin [action] => editor [args] => [referrer] => Array ( [HTTP_REFERER] => [REMOTE_ADDR] => 127.0.0.1 [HTTP_VIA] => [HTTP_X_FORWARDED_FOR] => ) [get] => ) [request_status:Request:private] => 200 )
Это образец моего манифеста:
[controller] => Array ( [icontroller] => /htdocs/raspberry/raspberry/core/controller/icontroller.class.php [index] => /htdocs/raspberry/raspberry/core/controller/index.php [serviceerror] => /htdocs/raspberry/raspberry/core/controller/serviceerror.controller.php [admin] => /htdocs/raspberry/raspberry/vendors/core/admin/controller/admin.controller.ph [composer] => /htdocs/raspberry/raspberry/vendors/core/admin/controller/composer.controller.php )
Это файловая система приложения:
http://img.ruphp.com/vendor/Screen_shot_2012-10-09_at_8.45.27_PM.png
Проблема, похоже, вызвана чрезмерно упрощенным механизмом маршрутизации. Создается впечатление, что вы используете простой explode()
для сбора параметров из URL. Хотя это работает только в базовых примерах, установка завершится неудачно, когда вы попытаетесь использовать несколько более совершенные схемы маршрутизации.
Вместо того, чтобы разбивать строку на /
, вы должны сопоставлять ее с шаблонами regexp. В основном, вы определяете список шаблонов для соответствия, и первое совпадение используется для заполнения экземпляра Request
.
В вашей ситуации было бы определено два шаблона:
'#admin/(:?(:?/(?P<controller>[^/\.,;?\n]+))?/(?P<action>[^/\.,;?\n]+))?#'
'#(:?(:?/(?P<controller>[^/\.,;?\n]+))?/(?P<action>[^/\.,;?\n]+))?#'
Если первый не удастся, второй будет соответствовать.
PS Вы должны знать, что контроллеры не должны выводить вывод. Генерация ответа – это ответственность за просмотр экземпляров. Представления должны быть полностью функциональными объектами, которые содержат логику представления и могут составлять ответ от нескольких шаблонов.