Библиотека модулей Zend Framework
Я работаю над приложением Zend Framework (1.11), которое я портирую на модули, чтобы разработчики могли подключать и проигрывать различные дополнения к нашему программному обеспечению и удалять их так же легко.
У меня есть проблема (и, кажется, я не могу найти ответ на нее) у меня есть надежный библиотечный код, т.е. моя структура в настоящее время это
- application
- (the standard ZF stuff)
- modules
- testModule
- Bootstrap.php
- controllers
- configs
- views
- library
- CoreStuff
- Class.php
- SpecialClass.php
- testModuleLibrary
- Class.php
- SpecialClass.php
И что мне действительно нужно, так это чтобы другим разработчикам было проще устанавливать модули в нашу систему.
- application
- (the standard ZF stuff)
- modules
- testModule
- Bootstrap.php
- controllers
- configs
- views
- library
- Class.php
- SpecialClass.php
- library
- CoreStuff
- Class.php
- SpecialClass.php
Можно ли использовать автозагрузчик в модуле Bootstrap? или я должен добавить его в мой путь включения?
[РЕДАКТИРОВАТЬ]
Это мой текущий модуль начальной загрузки, я видел этот код снова и снова с моим опасным поиском, но, похоже, это не имеет никакого значения
<?php
class Notifications_Bootstrap extends Zend_Application_Module_Bootstrap {
protected function _initLibraryAutoloader () {
return $this->getResourceLoader()->addResourceType('library', 'library', 'library');
}
}
4 ответа
Я решил мою проблему с помощью следующего кода. Я буквально понятия не имею, почему я не придумал это раньше:(:(
class Notifications_Bootstrap extends Zend_Application_Module_Bootstrap {
protected function _initConfig () {
set_include_path(implode(PATH_SEPARATOR, array(
dirname(__FILE__) . '/library',
get_include_path(),
)));
}
}
Вы можете определить пути к вашей библиотеке в файле конфигурации приложения, например: Это пример в YML
project:
bootstrap:
path: APPLICATION_PATH/Bootstrap/index.php
class: Bootstrap_Index
Autoloadernamespaces:
- Zend_
- Library1_
- Library2_
resources:
FrontController:
moduledirectory:
- APPLICATION_PATH/modules
......
Вот пример в формате INI
[bootstrap]
Autoloadernamespaces[] = "Zend_"
Autoloadernamespaces[] = "Library1_"
Autoloadernamespaces[] = "Library2_"
resources.FrontController.moduleDirectory = APPLICATION_PATH"/modules"
resources.FrontController.resetRouterOnEveryRequest = true
bootstrap.path = APPLICATION_PATH "/Bootstrap/index.php"
bootstrap.class = "Bootstrap_Index"
Что касается структуры каталогов проекта, я советую вам использовать что-то похожее на:
- application
- Bootstrap
- index.php
- Modules
- Mod1
- controllers
- views
- Mod2
- controllers
- views
...
- library
- Zend
- ...
- Library1
- ...
- Library2
- ...
После создания структуры каталогов вы можете иметь URL-адреса, такие как /:module/:controller/:action, и хранить весь сторонний код отдельно в своем каталоге библиотеки пула.
Я добавляю этот ответ, чтобы, надеюсь, оба ответили на первоначальный запрос, а также предоставили некоторые разъяснения по нескольким пунктам, представленным здесь. Я активный разработчик модулей в ZF 1.11 и использую то, что я собираюсь объяснить каждый день, в одном из нескольких поддерживаемых нами модулей.
Я заранее извиняюсь за длину этого ответа. Есть несколько пунктов, чтобы покрыть и рассмотреть.
Во-первых, для реализации.
Следующий фрагмент, который был предоставлен, насколько я знаю, работал ~1.8 и не был бы тем, что вы хотите для 1.11.
<?php
class Notifications_Bootstrap extends Zend_Application_Module_Bootstrap {
protected function _initLibraryAutoloader () {
return $this->getResourceLoader()->addResourceType('library', 'library', 'library');
}
}
Следующее, хотя, работало бы хорошо при условии нескольких ключевых элементов, которые я объясню ниже.
protected function _initLibraryAutoloader () {
return $this->getResourceLoader()->addResourceType('library', 'library', 'Library_');
}
Вы заметите небольшую разницу в третьем параметре (пространстве имен). Лучшим объяснением этого может быть обновление функции следующим образом:
protected function _initLibraryAutoloader () {
$this->getResourceLoader()->addResourceType('library', 'library', 'Library_');
var_dump($this->getResourceLoader()->getResourceTypes());die;
}
Ваш вывод должен быть примерно таким:
Array
(
[dbtable] => Array
(
[namespace] => Admin_Model_DbTable
[path] => /path/to/trunk/application/modules/admin/models/DbTable
)
[mappers] => Array
(
[namespace] => Admin_Model_Mapper
[path] => /path/to/trunk/application/modules/admin/models/mappers
)
[form] => Array
(
[namespace] => Admin_Form
[path] => /path/to/trunk/application/modules/admin/forms
)
[model] => Array
(
[namespace] => Admin_Model
[path] => /path/to/trunk/application/modules/admin/models
)
[plugin] => Array
(
[namespace] => Admin_Plugin
[path] => /path/to/trunk/application/modules/admin/plugins
)
[service] => Array
(
[namespace] => Admin_Service
[path] => /path/to/trunk/application/modules/admin/services
)
[viewhelper] => Array
(
[namespace] => Admin_View_Helper
[path] => /path/to/trunk/application/modules/admin/views/helpers
)
[viewfilter] => Array
(
[namespace] => Admin_View_Filter
[path] => /path/to/trunk/application/modules/admin/views/filters
)
[library] => Array
(
[namespace] => Admin_Library
[path] => /path/to/trunk/application/modules/admin/library
)
)
Если вы сравните это с предыдущей "библиотекой" в качестве третьего параметра, через секунду вы поймете, почему это так важно.
Чтобы повторить, на данный момент вы объявили тип библиотеки с префиксом "Library_", что переводится как "Admin_Library". Теперь, чтобы реализовать это, у вас будет папка библиотеки в вашем модуле, как и в основном модуле приложения, с одной небольшой настройкой. Чтобы иметь действие контроллера для модуля Admin ( Admin_Library_Controller_Action), у вас будет библиотека /Controller/Action.php с именем класса Admin_Library_Controller_Action. Это то, что поначалу больше всего смущает, но очень похоже на другие пространства имен ресурсов, которые вы должны использовать в модулях.
Это завершает техническое объяснение. Если вы не будете читать дальше, вы сможете иметь библиотеку, специфичную для вашего модуля, и полностью автономную для простой реализации копирования / вставки повторно используемого модуля.
Теперь для нескольких комментариев о некоторых других ответах, которые я видел здесь.
отмечена бесконечность
"Если вы будете следовать своей структуре, вы можете получить - Module1 (Lib1, Lib2) - Module2 (Lib1, Lib3), поэтому вы начнете дублировать необходимые библиотеки".
Это технически правильно, но на самом деле выявляет больше проблем в вашем реальном стиле разработки, если вы постоянно используете одни и те же библиотеки повсюду. Обычно мы храним эти общие элементы в другой библиотеке, которую мы используем как внешнюю, идентичную Zend, и располагаем вдоль Zend в основной папке библиотеки приложения.
Если вы уже делаете это, я полагаю, что некоторые дополнительные пояснения могут потребоваться, если вы правильно используете пространства имен, вам абсолютно не нужно беспокоиться о столкновении имен библиотечных классов. Вы можете на короткое время обнаружить, что вам нужно иметь классы с одинаковым кодом в нескольких модулях, но как только это произойдет, вы должны рассмотреть общую библиотеку в дополнение к Zend, о котором я упоминал выше.
Еще раз извиняюсь за длину этого ответа. Я надеюсь, что это поможет любому, кто может столкнуться с этим постом, нуждающимся в реализации библиотеки в модулях.
Вы можете просто использовать модуль Boostrap.php. Обеспечить функцию
protected function _initAutoload(){}
сделать библиотеку доступной. Таким образом, вы можете просто сделать так, чтобы модуль-разработчик сделал это, так как это часть работы по разработке модуля, чтобы сделать его ресурсы загружаемыми:)