Intereting Posts
Что такое поздние статические привязки в PHP? получение выходного и выходного статуса из shell_exec () сложная манипуляция строк в PHP CakePHP Неопределенная радиокнопка изменена на нежелательное значение для отправки Получить сегмент uri в функции индекса контроллера – Codeigniter Санитирование значений массива перед вставками mysql Как обрабатывать пользовательские заголовки с запросом на предварительный рейс CORS? AJAX – CodeIgniter Справка с регулярным выражением для соответствия любому URL-адресу, а не папке администратора Заполнение динамического поля выбора с помощью значений mysql Отправить несколько значений из ajax в php в URL с помощью GET Catch PHP Fatal Error Начало работы с руководством по быстрому старту cakephp-file-storage Доступ к родительскому элементу элемента с помощью SimpleXML PHP? Если PHP mt_rand () использует более быстрый алгоритм, чем rand (), почему бы просто не изменить rand () для использования более новой реализации? Есть ли способ показать или бросить предупреждение PHP?

Как использовать одни и те же модели в разных модулях в Zend Framework?

Я работаю над внедрением Zend Framework в рамках существующего проекта, который имеет область публичного маркетинга, зону частных пользователей, сайт администрирования и сайт управления маркетинговой кампанией. В настоящее время они плохо организованы с помощью скриптов диспетчера для области маркетинга и области участников, находящихся под корнем сайта, а затем отдельной папки для администратора и другой папки для сайта маркетинговой кампании.

При реализации Zend Framework я хотел бы создать возможность разделить контроллеры и представления на модули (один для области участников, один для области публичного маркетинга, один для сайта администратора и один для сайта администрирования маркетинговой кампании) но мне нужно указать каждый модуль на ту же модель, поскольку все три компонента работают в одной и той же базе данных и на тех же бизнес-объектах.

Однако я не смог найти информацию о том, как это сделать в документации. Может ли кто-нибудь помочь с ссылкой о том, как это сделать или какие-то простые инструкции о том, как это сделать?

То, что я делаю, – это поддерживать общие классы в "библиотечном" каталоге за пределами иерархии модулей. Затем установите INCLUDE_PATH для использования каталога «models» соответствующего модуля, а также общей библиотеки «library».

 docroot/ index.php application/ library/ <-- common classes go here default/ controllers/ models/ views/ members/ controllers/ models/ views/ admin/ controllers/ models/ views/ . . . 

В моем скрипте bootstrap я добавляю « application/library/ » в INCLUDE_PATH . Затем в функции init() каждого контроллера я добавляю каталог « models/ » этого модуля в INCLUDE_PATH .

edit: такие функции, как setControllerDirectory() и setModuleDirectory() , не добавляют соответствующие каталоги моделей в INCLUDE_PATH . Вы должны сделать это сами в любом случае. Вот один пример того, как это сделать:

 $app = APPLICATION_HOME; // you should define this in your bootstrap $d = DIRECTORY_SEPARATOR; $module = $this->_request->getModuleName(); // available after routing set_include_path( join(PATH_SEPARATOR, array( "$app{$d}library", "$app{$d}$module{$d}models", get_include_path() ) ) ); 

Вы можете добавить « library » к вашему пути в начальной загрузке, но вы не можете добавить каталог « models » для правильного модуля в bootstrap, потому что модуль зависит от маршрутизации. Некоторые люди делают это в методе init() своих контроллеров, а некоторые люди пишут плагин для кэша preDispatch ActionController для установки INCLUDE_PATH .

Это также можно выполнить с помощью соглашения об именах, чтобы следовать за Zend_Loader . Храните файлы модели в папке с образцами в папке с модулем. Назовите их как Module_Models_ModelName и сохраните их в имени файла ModelName.php в папке моделей для этого модуля. Убедитесь, что папка приложения находится в вашем пути включения и если вы используете Zend_Loader для автоматической загрузки, вы можете просто ссылаться на модели по их имени класса.

Это имеет то преимущество, что ваш код модели сгруппирован с фактическим модулем, для которого он предназначен. Это сохраняет модуль, содержащийся в одной структуре папок, что помогает поощрять инкапсуляцию. Это также поможет в будущем, если вам необходимо перенести модуль в другой проект.

Я просто создал этот пользовательский помощник действий для описанной проблемы:

 <?php class My_Controller_Action_Helper_GetModel extends Zend_Controller_Action_Helper_Abstract { /** * @var Zend_Loader_PluginLoader */ protected $_loader; /** * Initialize plugin loader for models * * @return void */ public function __construct() { // Get all models across all modules $front = Zend_Controller_Front::getInstance(); $curModule = $front->getRequest()->getModuleName(); // Get all module names, move default and current module to // back of the list so their models get precedence $modules = array_diff( array_keys($front->getDispatcher()->getControllerDirectory()), array('default', $curModule) ); $modules[] = 'default'; if ($curModule != 'default') { $modules[] = $curModule; } // Generate namespaces and paths for plugin loader $pluginPaths = array(); foreach($modules as $module) { $pluginPaths[ucwords($module)] = $front->getModuleDirectory($module) . '/models'; } // Load paths $this->_loader = new Zend_Loader_PluginLoader($pluginPaths); } /** * Load a model class and return an object instance * * @param string $model * @return object */ public function getModel($model) { $class = $this->_loader->load($model); return new $class; } /** * Proxy to getModel() * * @param string $model * @return object */ public function direct($model) { return $this->getModel($model); } } 

Итак, в вашем Bootstrap.php:

 Zend_Controller_Action_HelperBroker::addPrefix('My_Controller_Action_Helper'); 

И в любом из ваших контроллеров:

 <?php class IndexController extends Zend_Controller_Action { public function indexAction() { $model = $this->_helper->getModel('SomeModel'); } } 

И это позволит вам получить доступ к моделям любого контроллера во всех модулях.

У меня такая же проблема. Ответ Билла не подходит для меня – потому что я склонен разделить мои модули, а не «кто их видит», а «что они делают». Например, «форум-модуль» может управляться как администратором, так и общественностью. Я пытаюсь иметь модули переднего плана, такие как admin, members, public, но затем они используют другие модули, такие как «forum / validatepost», «форум / показать пользователям личную информацию». Если кто-то может пролить свет на то, как они защищают внутренний модуль от общественности, тогда это было бы удобно. Я думаю, что ACL может быть ключом, но он все еще заставляет меня нервничать, имея доступ, контролируемый объектами, в отличие от «файловой системы / .htaccess» и т. Д.

Чтобы ответить на вопрос PHPoet: (i) Пути к директориям диспетчера модулей могут быть заданы вызовами переднего контроллера: например, см. «12.11.2. Указание директорий контроллера модуля» (Zend Framework Docs)

(ii) Пути к представлениям могут быть установлены с помощью ViewRenderer (помощник действий контроллера), например, см. «Пример 12.12. Выбор другого сценария просмотра (документы Zend Framework)

Играя вокруг своего возможного, чтобы изменить пути по умолчанию к представлениям и контроллерам, освободив автозагрузчик для запуска в обычном режиме.

(Я не рассматривал способ работы автозагрузчика, но для него было бы целесообразно иметь некоторую систему картографов для решения этой проблемы).

 <?php return array( 'modules' => array( 'Application', 'DoctrineModule', 'DoctrineORMModule', 'Merchant', ), 'module_listener_options' => array( 'config_glob_paths' => array( 'config/autoload/{,*.}{global,local}.php', ), 'module_paths' => array( './module', '../vendor', // 'here we can load module' 'comomonmodule' ), ), );