Проблема с автозагрузкой моделей Zend

#zend-framework #namespaces #zend-autoloader

#zend-framework #пространства имен #zend-автозагрузчик

Вопрос:

Zend framework. Я хочу автоматически загрузить свои классы моделей внутри папки models из класса bootstrap. Эти модели фактически не используют никакого пространства имен (поэтому у меня есть Ex. User.php класс файла с именем User и так далее ..).

Если я правильно понял, я должен использовать Zend_Loader_Autoloader_Resource и я попытался:

 function _initLoaderResource() 
{         
    $resourceLoader = new Zend_Loader_Autoloader_Resource(array(                 
    'basePath'  => APPLICATION_PATH,//points to the "application" path where resides "models" folder
    'namespace' =>''       
    ));         

    $resourceLoader->addResourceType('models', 'models/');

} 
  

И я получаю следующее сообщение ‘Zend_Loader_Exception’:

 'Initial definition of a resource type must include a namespace' 
  

Мои вопросы:

  • Правильный ли это способ автоматической загрузки моделей?
  • Как я должен управлять кодом ресурса, который не соответствует стандарту кодирования Zend Framework?

Ответ №1:

На самом деле вы, вероятно, не хотите использовать автозагрузчик ресурсов для этого, поскольку (как вы обнаружили) для этого требуется пространство имен. Стандартный автозагрузчик (который загружает модели из включаемого пути) имеет опцию setFallbackAutoloader , которая сообщает ZF, что этот автозагрузчик следует использовать для любого класса, не соответствующего пространству имен, охватываемому другим. Итак, все, что вам нужно сделать, это убедиться, что ваш каталог models находится по пути включения и установите для этого параметра значение true.

Вероятно, вы уже используете стандартный автозагрузчик для загрузки классов Zend, поэтому, вероятно, захотите изменить свой файл application.ini, чтобы добавить каталог вашей модели во включаемый путь, а затем установить запасной вариант либо в application.ini, либо в вашем классе Bootstrap:

 protected function _initAutoloader()
{
    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->setFallbackAutoloader(true);

    return $autoloader;
}
  

Комментарии:

1. Ваш ответ идеален!! Спасибо

Ответ №2:

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

Вы могли бы начинать свои классы с определенного для приложения пространства имен или общего. пространства имен, такие как ‘My_’ или ‘App_’, являются общими, но, например, если ваше приложение называется Job Board, вы могли бы использовать пространства имен, такие как ‘JB_’, в ваших файлах классов.

Вы также можете написать свой собственный автозагрузчик (либо полностью новый, либо путем расширения автозагрузчика Zend) и зарегистрировать его как автозагрузчик SPL, чтобы обойти это.

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

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

     $nameSpaceToPath = array(
                            'Application'   => APPLICATION_PATH,
                            'Base'          => APPLICATION_PATH . '/base',
                            'Store'     => APPLICATION_PATH . '/modules/Store',
                            'Payment'     => APPLICATION_PATH . '/modules/Payment',
                            'Admin'     => APPLICATION_PATH . '/modules/Admin'
                        );

    foreach($nameSpaceToPath as $ns => $path) {
        $autoLoaderResource = new Zend_Loader_Autoloader_Resource(
                            array(
                                'basePath' => $path,
                                'namespace' => $ns
                            )
                        );
        $autoLoaderResource->addResourceType('controller','controllers','Controller');
        $autoLoaderResource->addResourceType('model','models','Model');
        $autoLoaderResource->addResourceType('mapper','models/mappers','Model_Mapper');
        $autoLoaderResource->addResourceType('service','services','Service');
        // I'm using _Util_ in the name of my utility classes, I place them in 'utils' directory
        $autoLoaderResource->addResourceType('util','utils','Util');
        $autoLoaderResource->addResourceType('plugin','plugins','Plugin');
        $autoLoaderResource->addResourceType('form','forms','Form');
        // I'm using _Exception_ in the name of my module specific exception classes, I place them in 'exceptions' directory
        $autoLoaderResource->addResourceType('exception','exceptions','Exception');
        $autoLoader->pushAutoloader($autoLoaderResource);
    }
  

Когда вы определяете тип ресурса, вызывая:

 $autoLoaderResource->addResourceType('service','services','Service');
  

На самом деле вы сообщаете Zend Autoloader, что у вас есть тип ‘service’ (1-й параметр), который помещен в каталог с именем ‘services’ (2-й параметр), и вы используете токен ‘Service‘ в именах классов для указания классов этого типа.

Приведенный выше код сообщает Zend автозагрузчику выполнить поиск класса Store_Service_Core в пути ‘APPLICATION_PATH/modules/store/services/Core.php ‘.

Как вы можете видеть, я зарегистрировал общее пространство имен «Application» для пути APPLICATION_PATH. Это означает, что каждый класс, начинающийся с Application_, будет автоматически загружаться из APPLICATION_PATH. Итак, для примера, у меня есть класс с именем Application_Init, который использует некоторые задачи инициализации, и теперь Zend автоматически загружает его с пути APPLICATION_PATH/Init.php .