Определенная соглашением модульная структура директорий позволяет разделять различные приложения MVC в автономные единицы и повторно использовать их с различными фронт-контроллерами. Ниже показан пример такой структуры:
docroot/ index.php application/ default/ controllers/ IndexController.php FooController.php models/ views/ scripts/ index/ foo/ helpers/ filters/ blog/ controllers/ IndexController.php models/ views/ scripts/ index/ helpers/ filters/ news/ controllers/ IndexController.php ListController.php models/ views/ scripts/ index/ list/ helpers/ filters/
В этой парадигме имена модулей используются как префиксы к контроллерам в этих модулях. Пример выше содержит три контроллера в модулях: 'Blog_IndexController', 'News_IndexController' и 'News_ListController'. Также определены два глобальных контроллера: 'IndexController' и 'FooController', для них не используются пространства имен. Эта структура директорий будет использоваться для примеров в данном разделе.
Нет пространств имен в модуле, используемом по умолчанию | |
---|---|
Обратите внимание, что в модуле, используемом по умолчанию, контролеры не нуждаются в префиксе пространства имен. В примере выше контроллеры в модуле по умолчанию не нуждаются в префиксе 'Default_' - они просто вызываются по их базовым именам контроллера: 'IndexController' and 'FooController'. Но для других модулей использование префикса пространства имен обязательно. |
Итак, как можно реализовать такую организацию на уровне директорий, используя компоненты MVC в Zend Framework?
Первым шагом в использовании модулей является изменение способа
определения списка директорий во фронт-контроллере. При обычном
использовании MVC вы передаете массив или строку методу
setControllerDirectory()
, либо путь методу
addControllerDirectory()
. В случае использования
модулей нужно несколько изменить вызовы этих методов.
Методу setControllerDirectory()
должен передаваться
ассоциативный массив, в котором пары ключ/значение содержат имя
модуля и путь к директории соответственно. Специальный ключ
'default' используется для глобальных контроллеров (которым не нужно
пространство имен модуля). Все записи должны содержать строковой
ключ, указывающий на единственный путь, при этом должен
присутствовать ключ default
. Например:
<?php $front->setControllerDirectory(array( 'default' => '/path/to/application/controllers', 'blog' => '/path/to/application/blog/controllers' ));
Метод addControllerDirectory()
принимает необязательный
второй параметр. Если используются модули, то передавайте имя модуля
в качестве второго аргумента; если он не определен, то путь будет
добавлен в пространство имен default
. Например:
<?php $front->addControllerDirectory('/path/to/application/news/controllers', 'news');
Лучшее напоследок: самый легкий способ определения
директорий модулей состоит в их одновременном определении, со всеми
модулями под общей директорией и использующими одну и ту же
структуру. Это может быть сделано с помощью
addModuleDirectory()
:
<?php /** * Предполагается следующая структура директорий: * application/ * modules/ * default/ * controllers/ * foo/ * controllers/ * bar/ * controllers/ */ $front->addModuleDirectory('/path/to/application/modules');
Пример выше определит модули default
, foo
и bar
, все они указывают на поддиректорию
controllers
соответствующих модулей.
Через метод setModuleControllerDirectoryName() можно указать
другую поддиректорию контроллеров для использования внутри
модулей
:
<?php /** * Изменяем поддиректорию для контроллеров на 'con' * application/ * modules/ * default/ * con/ * foo/ * con/ * bar/ * con/ */ $front->setModuleControllerDirectoryName('con'); $front->addModuleDirectory('/path/to/application/modules');
Замечание | |
---|---|
Вы можете указать, что для модулей не должна использоваться
поддиректория для контроллеров путем передачи пустого значения
методу |
Маршрут, используемый по умолчанию в
Zend_Controller_Router_Rewrite
, является объектом типа
Zend_Controller_Router_Route_Module
. Этот маршрут
использует один из следующих шаблонов маршрутизации:
:module/:controller/:action/*
:controller/:action/*
Другими словами, он будет соответсвовать контроллеру и действию без модуля или контроллеру и действию с предшествующим модулем. Правила сопоставления предписывают, что URL должен только тогда соответствовать модулю, если ключ с тем же именем существует в массиве директорий контроллеров, переданного фронт-контроллеру и диспетчеру.
В маршрутизаторе, используемом по умолчанию, если контроллер не был
указан в URL, то используется контроллер по умолчанию
(IndexController
, если не был установлен другой). В
случае использования модулей, если был указан модуль без
контроллера, то диспетчер сначала ищет используемый по умолчанию
контроллер в директории модуля, затем в глобальном пространстве имен
'default'.
Если хотите всегда использовать глобальное пространство имен, то
установите параметр useGlobalDefault
во
фронт-контроллере:
<?php $front->setParam('useDefaultControllerAlways', true);