Magento для PHP MVC разработчиков – разбор контроллера (ч.2/11)
Архитектура Model-View-Controller (MVC) походит из языка программирования Smalltalk и Xerox Parc. С тех пор появилось много новых систем, которые описывают свою архитектуру как MVC. Каждая система отличается, но все они ставят своей целью разделения доступа к данным, бизнес-логике и интерфейсу.
Архитектура большинства PHP MVC фреймворков будет выглядеть примерно так:
- URL перехватывается особым PHP файлом (обычно называется Front Controller)
- Этот PHP-файл проанализирует URL, получит имя контроллера и имя действия (Action): этот процесс часто называется маршрутизацией (routing)
- Полученный контроллер будет в качестве нового экземпляра
- Полученное название метода сравнивается с полученным именем действия (Action), вызываемым в контроллере
- Этот экшен характеризует и вызывает методы моделей, зависимых от переменных запроса (request)
- Метод Экшена (Action) также подготовит структуру данных информации, которая будет передана View
- View затем генерирует HTML, используя информацию в структуре данных, полученную от контроллера.
В то время, как данная модель является большим шагом вперед (от паттерна «каждый файл является страницей», который был в начале), для некоторых программистов это все еще кажется «неотесанным». Общими претензиями к подобной модели являются:
- PHP-файл Front Controller’а до сих пор оперирует в глобальном пространстве имен
- Сборка над конфигурацией приводит к меньшей модульности
- URL-адреса маршрутизации часто не гибкие
- Контроллеры часто привязаны к конкретным Views
- Даже тогда, когда система предлагает способ переопределения базовых значений (defaults), сборка приводит к приложениям, в которых становится трудно/невозможно отказываться от накопления все новых моделей, или реализаций контроллера без массивного рефакторинга.
Как вы, наверное, догадались, команда Magento поддерживает это мировоззрение и создала более абстрактный MVC-шаблон, который выглядит примерно так:
- URL перехватывается в отдельном PHP файле
- Этот PHP-файл создает экземпляр аппликации Magento
- Аппликация Magento создает экземпляр объекта Front Controller
- Front Controller создает экземпляры любого количества маршрутов (Router), указанных в глобальной конфигурации
- Маршрутизаторы (Routers) проверяют запрашиваемый URL для нахождения «совпадения»
- Если совпадение найдено, контроллер и метод-действие (Action) выполняются
- Экшен Контроллер становится экземпляром и вызывается метод, название которого совпадает с именем действия (Action Name)
- Этот метод действия (Action) станет экземпляром и вызовет методы из моделей, в зависимости от запроса
- Этот контроллер затем будет экземпляром объекта макета (Layout Object)
- Этот объект макета будет, основываясь на некоторых переменных запроса и параметров системы (также известных как «handles»), создавать набор объектов Блоков, которые являются действительными для данного запроса
- Макет (Layout) также будет вызывать метод вывода в определенных объектах Блока (Block), которые начинают вложенный рендеринг (Блоки будут содержать в себе другие Блоки)
- Каждый Блок коррелирует с соответствующим файлом шаблона (Template). Блоки содержат PHP-логику, а шаблоны содержат HTML и PHP код для вывода данных пользователю.
- Блоки обращаются непосредственно к моделям за своими данными. Иными словами, контролеры не передают им структуру данных
Мы, со временем, подробнее осмотрим каждую часть этого процесса, но сейчас мы сосредоточимся на секции Front Controller -> Routers -> Action Controller
Hello World
Достаточно теории, пришла пора создать Hello World. Мы собираемся:
- Создать модуль Hello World в системе Magento
- Настроить этот модуль с маршрутизацией (routes)
- Создать контроллер(ы) для наших маршрутов (routes)
Создаем модуль Hello World
Во-первых, мы создадим структуру папок для этого модуля. Наша структура папок должна выглядеть следующим образом (вы должны использовать свое пространство имен):
app/code/local/Alanstormdotcom/Helloworld/Block app/code/local/Alanstormdotcom/Helloworld/controllers app/code/local/Alanstormdotcom/Helloworld/etc app/code/local/Alanstormdotcom/Helloworld/Helper app/code/local/Alanstormdotcom/Helloworld/Model app/code/local/Alanstormdotcom/Helloworld/sql
Затем создаем конфигурационный файл для этого модуля (по адресу app/code/local/Alanstormdotcom/Helloworld/etc/config.xml
):
<config> <modules> <Alanstormdotcom_Helloworld> <version>0.1.0</version> </Alanstormdotcom_Helloworld> </modules> </config>
Затем создаем файл для активации модуля (по адресу app/etc/modules/Alanstormdotcom_Helloworld.xml
):
<config> <modules> <Alanstormdotcom_Helloworld> <active>true</active> <codePool>local</codePool> </Alanstormdotcom_Helloworld> </modules> </config>
Наконец убеждаемся, что наш модуль активен:
- Очистите кэш Magento
- В административной панели Magento перейдите к System -> Configuration -> Advanced
- Разверните «Disable Modules Output» (Отключение вывода модулей «) (если не развернуто)
- Убедитесь, что появился модуль
Alanstormdotcom_Helloworld
.
Настройка маршрутизации
Далее мы собираемся настроить маршрутизацию (routes). Маршрутизация будет превращать URL-запрос в действие (Action Controller) и метод. В Magento, в отличие от других PHP MVC-систем, вы должны явно определять маршрутизацию (routes) в глобальной Magento-конфигурации.
В файл config.xml
добавьте следующую секцию:
<config> ... <frontend> <routers> <helloworld> <use>standard</use> <args> <module>Alanstormdotcom_Helloworld</module> <frontName>helloworld</frontName> </args> </helloworld> </routers> </frontend> ... </config>
Здесь у нас есть много новых терминов, давайте разберем их.
Что такое <frontend>
?
Тег <frontend>
относится к областям (Area) Magento. Сейчас думайте об областях, как об индивидуальных Magento-приложениях. Область «frontend» – это внешний вид приложения Корзины Мадженто. Область «admin» – это приватное приложение административной консоли. Область «install» – это приложение, которое вы используете для запуска процесса установки Magento.
Почему теги <routers>
настроены на индивидуальные маршруты?
Есть известная цитата о компьютерной науке, которую часто связывают с Филом Карлтоном:
«Есть только две тяжелые вещи в компьютерной науке: валидация кэша и именование вещей»
Magento, как и все большие системы, страдает от проблем избыточного именования. Вы найдете много мест в глобальном настройке (global config), и в системе в целом, где именование интуитивно непонятное, или даже совсем неоднозначное. Маршрутизация – одно из таких мест.
Что такое <frontName>
?
Когда маршрутизатор (router) анализирует URL, то он получает разделенные запросы
VASH-DOMEN/frontName/actionControllerName/actionMethod/
Поэтому, при определении «helloworld» в <frontName>
теге, мы говорим Magento, что нам нужен ответ URL в виде
VASH-DOMEN/helloworld/*
Многие новички в Magento путают этот frontName с объектом Front Controller. Это не то же самое. FrontName относится исключительно к маршрутизации (routers).
Для чего тег <helloworld>
?
Этот тег должен именоваться именем модуля в нижнем регистре. У нас модуль Helloworld, значит имя тега – helloworld. Этот тег, технически, определяет название нашего маршрута.
Вы также заметите, что наш frontName совпадает с именем нашего модуля. Это свободная конвенция, чтобы frontName’ы совпадали с названиями модулей, но это не является обязательным требованием. На самом деле, один модуль может определять несколько <routers>
и, как результат, может иметь несколько frontName.
Для чего нужен <module>Alanstormdotcom_Helloworld</module>
?
Этот тег должен содержать полное название вашего модуля, включая имя package/namespace
. Это будет использоваться системой для размещения (определение) наших файлов контроллера.
Создание Action Controller(ов) для наших маршрутов (Routes)
Последний шаг, и у нас будет свой контроллер. Создайте файл в:
app/code/local/Alanstormdotcom/Helloworld/controllers/IndexController.php
Со следующим содержанием:
class Alanstormdotcom_Helloworld_IndexController extends Mage_Core_Controller_Front_Action { public function indexAction() { echo 'Hello World!'; } }
Очистите кэш и загрузите веб-страницу по следующей ссылке:
VASH-DOMEN/helloworld/index/index
Также, вы должны проверить загрузку страниц:
VASH-DOMEN/helloworld/index/ VASH-DOMEN/helloworld/
Должна появиться пустая страница с текстом «Hello World!». Поздравляем, вы настроили свой первый контроллер Magento!
Где размещаются контролеры?
Контроллеры должны быть размещены в модуле, в папке «controllers» (название в нижнем регистре). Это то место, где система будет искать их.
Как назвать контролеры?
Помните тег <module>
, содержащийся в config.xml
?
<module>Alanstormdotcom_Helloworld</module>
Название контроллера будет:
- Начинаться со строки, указанной в config.xml (
Alanstormdotcom_Helloworld
) - С дальнейшим нижним подчеркиванием (
Alanstormdotcom_Helloworld_
) - Которое будет сопровождаться названием экшен контроллера (
Alanstormdotcom_Helloworld_Index
) - И, наконец, слово «Controller» (
Alanstormdotcom_Helloworld_IndexController
)
Все Action контроллеры должны расширять класс Mage_Core_Controller_Front_Action
.
index/index
– что это за нонсенс?
Как упоминалось ранее, все URL в Magento ведут (по умолчанию) по адресу
VASH-DOMEN/frontName/actionControllerName/actionMethod/
Таким образом, в URL
VASH-DOMEN/helloworld/index/index
частица URI «helloworld» – является frontName, за которым следует индекс (имя Action контроллера), за которым следует другой индекс, который является именем Action метода, который будет вызываться. (Экшен index будет вызывать метод public function indexAction(){...}
.)
Если URL является неполным, Magento использует «index» по умолчанию. Поэтому, следующие адреса эквивалентны:
VASH-DOMEN/helloworld/index/ VASH-DOMEN/helloworld/
Если бы у нас был URL в таком виде
VASH-DOMEN/checkout/cart/add
тогда Magento будет:
- Обращаться к глобальной конфигурации, чтобы найти модуль для frontName checkout (
Mage_Checkout
) - Искать Action контроллер корзины (
Mage_Checkout_CartController
) - Вызвать метод
addAction
в контроллере корзины
Другие приемы контроллера
Давайте попробуем добавить нестандартный метод к нашему контроллеру. Добавьте следующий код в файл IndexController.php
public function goodbyeAction() { echo 'Goodbye World!'; }
и перейдите по URL для проверки
VASH-DOMEN/helloworld/index/goodbye
Поскольку мы расширяем класс Mage_Core_Controller_Front_Action
, это дает нам некоторые методы бесплатно. Например, дополнительные элементы URL, которые автоматически разбираются на пары key/value. Добавьте следующий метод к контроллеру.
public function paramsAction() { echo '<dl>'; foreach($this->getRequest()->getParams() as $key=>$value) { echo '<dt><strong>Param: </strong>'.$key.'</dt>'; echo '<dl><strong>Value: </strong>'.$value.'</dl>'; } echo '</dl>'; }
и посетите следующий URL
VASH-DOMEN/helloworld/index/params?foo=bar&baz=eof
Вы должны увидеть вывод каждого параметра и его значение.
Наконец, что нам нужно сделать, если бы мы хотели URL вида
VASH-DOMEN/helloworld/messages/goodbye
Здесь имя экшн контроллера messages, поэтому мы должны создать файл в
app/code/local/Alanstormdotcom/Helloworld/controllers/MessagesController.php
с названием контроллера
Alanstormdotcom_Helloworld_MessagesController
и методом, который выглядел бы примерно так
public function goodbyeAction() { echo 'Another Goodbye'; }
И это только поверхностное описание того, как Magento реализует контроллерную часть MVC. Хотя это немного сложнее, чем в других PHP MVC-фреймворках. Но эта система очень гибкая, и она позволит вам построить практически любую структуру URL, которую только пожелаете.
Автор: Alan Storm (http://alanstorm.com/magento_controller_hello_world/)
Перевод на русский: SebWeo
Предыдущая статья темы: Magento для PHP MVC разработчиков (Alan Storm) – ч.1/11
Все статьи данной серии:
- Magento для PHP MVC разработчиков (Alan Storm) – ч.1/11
- Magento для PHP MVC разработчиков – разбор контроллера (ч.2/11)
- Magento для PHP MVC разработчиков – Макеты, Блоки и Шаблоны (ч.3/11)
- Magento для PHP MVC разработчиков – Модели и основы ORM (ч.4/11)
- Magento для PHP MVC разработчиков – Инсталлирование Ресурса (ч.5/11)
- Magento для PHP MVC разработчиков – Расширенный ORM – EAV (ч.6/11)
- Magento для PHP MVC разработчиков – Особая конфигурация системы (ч.7/11)
- Magento для PHP MVC разработчиков – Углубленная настройка системы (ч.8/11)
- Magento для PHP MVC разработчиков – Коллекции Varien Data (ч.9/11)
- Magento для PHP MVC разработчиков – Переопределение и обновляемость системы (ч.10/11)
- Magento для PHP MVC разработчиков – Конфигурация системы по умолчанию (ч.11/11)