Модуль автозагрузчика в ZF - PullRequest
1 голос
/ 11 мая 2010

В руководстве по Zend_Application_Module_Autoloader указано следующее:

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

Источник: http://framework.zend.com/manual/zh/zend.loader.autoloader-resource.html#zend.loader.autoloader-resource.module

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

Теперь у меня два вопроса

  • Что такое дискретный модуль?
  • Есть ли способ зарегистрировать этот автозагрузчик ресурсов по умолчанию для каждого модуля без необходимости создавать файл начальной загрузки для каждого модуля? Я хочу, чтобы он был доступен в каждом модуле, и создание такого количества пустых классов начальной загрузки - это то, что я бы предпочел предотвратить.

Ответы [ 5 ]

7 голосов
/ 11 мая 2010

Я понимаю ваше нежелание добавлять пустой класс начальной загрузки к каждому модулю. Однако рассмотрим случай повторного использования: если вы можете объединить свой модуль отдельно, вы можете затем поместить его в другое приложение, и автозагрузка будет работать немедленно, без дополнительной работы. Это был один из вариантов использования начальной загрузки модуля и почему он в настоящее время работает так, как работает.

(«Дискретный» в данном случае означает «автономный», а не является частью модуля «приложение».)

Если вам не нравится, как это работает, вы можете опустить загрузчик модуля - вам просто нужно каким-то образом добавить автозагрузчик ресурса для модуля. Это можно сделать с помощью метода начальной загрузки довольно легко. Однако, как кто-то ранее писал: зачем изобретать велосипед, когда что-то, что проверено и задокументировано, выполняет свою работу? :)

2 голосов
/ 03 апреля 2011

Есть два способа (о которых я знаю), чтобы включить автозагрузчики ресурсов модуля. Первый был рассмотрен в ответах выше, а именно:

Добавьте строку ресурсов модулей в ваш application.ini:

resources.modules[] =

А затем создайте пустой файл начальной загрузки модуля.

Второй - добавить следующий метод начальной загрузки к вашей начальной (немодульной) начальной загрузке:

protected function _initModuleAutoload()
{
    $autoloader = new Zend_Application_Module_Autoloader(array(
        'namespace' => 'Foo',
        'basePath' => APPLICATION_PATH . "/modules/Foo",
    ));
    return $autoloader;
}

Но вам нужно будет создать автозагрузчик каждого модуля индивидуально. Лично я предпочитаю пустые файлы начальной загрузки по причинам, упомянутым выше - мне кажется, это больше руководство.

Примечание: я полагаю, что это "метод ресурсов начальной загрузки", который @weierophinney упоминает выше.

2 голосов
/ 11 мая 2010

Модули позволяют разделить ваше приложение на конкретные проблемы. Часто мои большие приложения будут иметь модуль по умолчанию для пользователей и модуль администратора, который будет содержать все административные функции. Я использую структуру каталогов, рекомендованную в разделе Рекомендуемая структура проекта для приложений Zend Framework MVC -> Структура модуля в документации Zend Framework.

Что касается вашего второго вопроса, ответ - да и нет. Если вы хотите воспользоваться преимуществами функции автозагрузки по умолчанию (загрузка Admin_Form_Settings из каталога admin / forms), вам потребуется загрузчик в каждом модуле. См. Статью Мэтью Вейера О'Финни о Модульных бутстрапах в Zend Framework: что нужно и чего не нужно для получения дополнительной информации. Вы также можете зайти в Google и просмотреть пост Роба Аллена «Модули начальной загрузки в ZF 1.8 и выше».

Отвечая нет на ваш второй вопрос: мне нравится использовать одну технику, которая не требует пустых загрузчиков в каждом модуле, - это поместить все классы вашего приложения в папку lib приложения и имитировать структуру каталогов Zend Framework. Если мое приложение с именем Example, я создам папку с именем Example в моей директории / lib. Моя форма регистрации пользователя будет помещена в / lib / Example / Form и может называться UserRegistration.php. Мой класс будет называться Example_Form_UserRegistration. Для автозагрузки моей формы в файле Bootstrap.php потребуется следующее:

protected function _initAppAutoload() {

    $autoloader = Zend_Loader_Autoloader::getInstance();

    return $autoloader;
}

Мой application.ini будет содержать строки

resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules[] = 
autoloaderNamespaces[] = "Example_"

Используя эту технику, вы сможете автоматически загружать любой класс в / lib / Example в любом месте вашего приложения, не помещая пустые загрузочные ловушки в каждый модуль.

ПРИМЕЧАНИЕ. Я пытался разместить ссылки непосредственно на документы и на статью Роба Аллена, но, поскольку я новичок, мне разрешили только одну ссылку. Извиняюсь за то, что прошу вас к элементам Google, которые должны быть ссылками.

2 голосов
/ 11 мая 2010

Причина, по которой модули начальной загрузки модулей включают автозагрузку, заключается в том, что они расширяют Zend_Application_Module_Bootstrap, который устанавливает автозагрузчик в конструкторе следующим образом:

public function __construct($application)
{
  //...
  if ($application->hasOption('resourceloader')) {
      $this->setOptions(array(
          'resourceloader' => $application->getOption('resourceloader')
      ));
  }
  $this->initResourceLoader();
  //...
}

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

       foreach ($modules as $module => $moduleDirectory) {
        $bootstrapClass = $this->_formatModuleName($module) . '_Bootstrap';
        if (!class_exists($bootstrapClass, false)) {
            $bootstrapPath  = dirname($moduleDirectory) . '/Bootstrap.php';
            if (file_exists($bootstrapPath)) {
                $eMsgTpl = 'Bootstrap file found for module "%s" but bootstrap class "%s" not found';
                include_once $bootstrapPath;
                if (($default != $module)
                    && !class_exists($bootstrapClass, false)
                ) {
                    throw new Zend_Application_Resource_Exception(sprintf(
                        $eMsgTpl, $module, $bootstrapClass
                    ));
                } elseif ($default == $module) {
                    if (!class_exists($bootstrapClass, false)) {
                        $bootstrapClass = 'Bootstrap';
                        if (!class_exists($bootstrapClass, false)) {
                            throw new Zend_Application_Resource_Exception(sprintf(
                                $eMsgTpl, $module, $bootstrapClass
                            ));
                        }
                    }
                }
            } else {
                continue;
            }
        }

        if ($bootstrapClass == $curBootstrapClass) {
            // If the found bootstrap class matches the one calling this
            // resource, don't re-execute.
            continue;
        }

        $moduleBootstrap = new $bootstrapClass($bootstrap);
        $moduleBootstrap->bootstrap();
        $this->_bootstraps[$module] = $moduleBootstrap;
    }

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

0 голосов
/ 04 августа 2012

Bootstrap:

$uri = explode('/',$_SERVER['REQUEST_URI']);
if($uri['1'] == 'flok'){
    $flok = new Zend_Controller_Router_Route('flok/:controller/:action/:id/*',  array('module' => 'flok', 'controller' => 'index', 'action' => 'index',  'id' =>null));
    $router->addRoute('flok', $flok);

    $resourceLoader = new Zend_Application_Module_Autoloader(array(
        'basePath'  => APPLICATION_PATH . "/flok/flok",
        'namespace' => 'Flok',
    ));

    //Init
    $frontController->registerPlugin(new Flok_Plugin_Init(),'flok');
    //Auth
    $frontController->registerPlugin(new Flok_Plugin_Auth(),'flok');

    // dynamic modules
    $ruta = APPLICATION_PATH.'/flok';
    foreach(scandir($ruta) as $mod) {
        if(!is_dir($mod) and $mod != '.DS_Store'){
            $Modululflok = new Zend_Controller_Router_Route('flok/'.$mod.'/:controller/:action/:id/*',  array('submodules' => 'flok','module' => $mod , 'controller' => 'index', 'action' => 'index',  'id' =>null));
            $router->addRoute($mod, $Modululflok);
            $resourceLoader = new Zend_Application_Module_Autoloader(array(
                'basePath'  => APPLICATION_PATH . "/flok/".$mod,
                'namespace' => ucfirst($mod),
            ));
        }
    }

    $layout = Zend_Layout::getMvcInstance();

    $layout
        ->setLayout('layout')
        ->setLayoutPath(APPLICATION_PATH . '/flok/flok/views/scripts');

    $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
    $viewRenderer->initView();
    $viewRenderer->view->addHelperPath(APPLICATION_PATH . '/flok/flok/helpers');
} else {
    $default = new Zend_Controller_Router_Route('*',  array('module' => 'default', 'controller' => 'index', 'action' => 'index'));
    $router->addRoute('default', $default);
}

Этот помощник для вставки данных (меню, представления и т. Д.) В основной модуль:

class Zend_View_Helper_Models
{
    public function Models($tipo)
    {
        // load modules
        $ruta = APPLICATION_PATH.'/flok';
        foreach(scandir($ruta) as $mod) {
            if(!is_dir($mod) and $mod != '.DS_Store'){
                $rutaphp = $ruta.'/'.$mod.'/'.$mod.'.php';
                if(file_exists($rutaphp)){ 
                include_once($rutaphp);
                    $modul = new $mod;
                    if(isset($modul->$tipo) and $modul->$tipo === true){
                       $data = $tipo.'Data';
                       $m[] = $modul->$data;
                    } 
                }
            }
        }
        return $m;
    }

} 
...