Programmer's Reference Guide
| Плагины |
Использование модульной структуры директорий
Введение
Определенная соглашением модульная структура директорий позволяет разделять различные приложения 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. Например:
- 'default' => '/path/to/application/controllers',
- 'blog' => '/path/to/application/blog/controllers'
- ));
Метод addControllerDirectory() принимает необязательный
второй параметр. Если используются модули, то передавайте имя модуля
в качестве второго аргумента; если он не определен, то путь будет
добавлен в пространство имен default. Например:
- $front->addControllerDirectory('/path/to/application/news/controllers',
- 'news');
Лучшее напоследок: самый легкий способ определения
директорий модулей состоит в их одновременном определении, со всеми
модулями под общей директорией и использующими одну и ту же
структуру. Это может быть сделано с помощью
addModuleDirectory():
- /**
- * Предполагается следующая структура директорий:
- * application/
- * modules/
- * default/
- * controllers/
- * foo/
- * controllers/
- * bar/
- * controllers/
- */
- $front->addModuleDirectory('/path/to/application/modules');
Пример выше определит модули default, foo
и bar, все они указывают на поддиректорию
controllers соответствующих модулей.
Через метод setModuleControllerDirectoryName() можно указать
другую поддиректорию контроллеров для использования внутри
модулей:
- /**
- * Изменяем поддиректорию для контроллеров на 'con'
- * application/
- * modules/
- * default/
- * con/
- * foo/
- * con/
- * bar/
- * con/
- */
- $front->setModuleControllerDirectoryName('con');
- $front->addModuleDirectory('/path/to/application/modules');
Замечание: Вы можете указать, что для модулей не должна использоваться поддиректория для контроллеров путем передачи пустого значения методу
setModuleControllerDirectoryName().
Маршрутизация применительно к модулям
Маршрут, используемый по умолчанию в Zend_Controller_Router_Rewrite, является объектом типа Zend_Controller_Router_Route_Module. Этот маршрут использует один из следующих шаблонов маршрутизации:
:module/:controller/:action/*:controller/:action/*
Другими словами, он будет соответсвовать контроллеру и действию без модуля или контроллеру и действию с предшествующим модулем. Правила сопоставления предписывают, что URL должен только тогда соответствовать модулю, если ключ с тем же именем существует в массиве директорий контроллеров, переданного фронт-контроллеру и диспетчеру.
Модуль или глобальный контроллер по умолчанию
В маршрутизаторе, используемом по умолчанию, если контроллер не был
указан в URL, то используется контроллер по умолчанию
(IndexController, если не был установлен другой). В
случае использования модулей, если был указан модуль без
контроллера, то диспетчер сначала ищет используемый по умолчанию
контроллер в директории модуля, затем в глобальном пространстве имен
'default'.
Если требуется всегда использовать глобальное пространство имен, то
установите параметр useGlobalDefault во
фронт-контроллере:
- $front->setParam('useDefaultControllerAlways', true);
| Плагины |
Add A Comment
Please do not report issues via comments; use the ZF Issue Tracker.
If you have a JIRA/Crowd account, we suggest you login first before commenting.
Select a Version
Languages Available
Components
Search the Manual
Navigation
- Руководство разработчика
- Руководство разработчика
- Справочное руководство Zend Framework
- Zend_Controller
- Zend_Controller - Быстрый старт
- Основы Zend_Controller
- Фронт-контроллер
- Объект запроса
- Стандартный маршрутизатор
- Диспетчер
- Контроллеры действий
- Помощники действий
- Объект ответа
- Плагины
- Использование модульной структуры директорий
- Исключения

Comments
where the default module is a level higher than the modules directory.
yes
This is the same problem throughout the ZF documentation! Stop crapping on about how awesome the framework is and put the examples in CONTEXT!
The layout shipped with ZF is implemented as a front controller plugin.
You can easily extend that one and work some magic to switch the layout according to the requested module. And configure the layout resource to use your own class.
My take (on pastebin) :
http://pastebin.org/358208
And in application.ini :
resources.layout.layout = layout
resources.layout.layoutPath = APPLICATION_PATH "/views/layouts"
resources.layout.pluginClass = "My_Controller_Plugin_ModuleLayout"
See: http://www.theinquirer.net/inquirer/news/1023739/windows
I've tried to configure in my bootstrap,
public function run()
{
parent::run();
$front = $this->getResource('FrontController');
$front->addModuleDirectory('application/modules');
}
and this appears to work (no exceptions thrown) but to no avail, I still need to include or require.
In which file?
The following should be added to your Bootstrap.php file.
protected function _initFrontModules() {
$this->bootstrap('frontController');
$front = $this->getResource('frontController');
$front->addModuleDirectory(APPLICATION_PATH . '/modules');
}
The following should be added to your Bootstrap.php file.
protected function _initFrontModules() {
$this->bootstrap('frontController');
$front = $this->getResource('frontController');
$front->addModuleDirectory(APPLICATION_PATH . '/modules');
}
Why not explore some example rather than commend.
Example gere : http://updel.com/zend-framework-modular-application/
I was starting to again feel like, if I don't just know, then why am at Zend.com trying to find the answer. I mean, c'mon, with the above being so clear now. pff
application
default
controllers
models
views
admin
controllers
models
views
and i want to keep all my models in default/models and all modules can use. How can i do this???
When i made the class 'Apllication_Model_Test' the class was not found. What and WHERE i have to set up for i use my models on all modules?
Thanks for any help!!!
Renan30
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules=true
and removing the line
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
I used zend tool:
zf create module default
Which adds a directories into : APPLICATION_PATH /modules/default
and appends to the application.ini config file:
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.params.prefixDefaultModule = "1"
I then moved my IndexController, ErrorController and view scripts into the default module's appropriate directories but got this error:
Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller class ("Default_ErrorController")'Removing this line from application.ini solves this problem:
resources.frontController.params.prefixDefaultModule = "1"resources.frontController.params.prefixDefaultModule = ""
$ front-> setControllerDirectory (array (
'default' => '/ path / to / application / controllers',
'blog' => '/ path / to / application / blog / controllers'
));
All examples, tutorials or the vast majority do not understand what part they copied the codes mentioned, that I tell people that just start with zend.
I solved the problem by using this:
resources.frontController.prefixDefaultModule = "Default"
Don't remove "Default" from ErrorController because it seems not to be natural. What if you don't want the default module named "default"? :)
And how can i load a model class which is located in "modules/news/models/news.php"?
It depends exactly on how you have named things. Here is how I solved the same problem.
My file structure is:
application > modules > module which contains a folder for controllers, models, views and a Bootstrap.php file.
My module Bootstrap.php file is:
class modulename_Bootstrap extends Zend_Application_Module_Bootstrap
{
}
I created a basic model which looks something like this:
class Module_Model_Bio
{
public function fetchAll()
{
// fetch all records from the table
$rowset = $this->_dbTable->fetchAll();
return $rowset->toArray();
} //end fetchAll
}
Then in my controller, I can instantiate this model with the following (note the lowercase module after the keyword new):
class Module_BioController extends Zend_Controller_Action
{
public function indexAction()
{
[b]$bio = new module_Model_Bio();[/b]
$this->view->entries = $bio->fetchAll();
}
}
I could be wrong, but I believe it is lowercase because that is how my module was named and how it is written in my module's Bootstrap.php file. If I instantiate it in a different case (camel case) it will not be found.
Please note the rule following line:
[b]$bio = new module_Model_Bio();[/b]
should just be:
$bio = new module_Model_Bio();
http://www.ranweb.net/wpEn/?p=406
Maybe it will help somebody...