Антон Шевчук // Web-разработчик

Zend Framework hacks // PHP

Zend Framework Hacks

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

Структура проекта на ZF

На данный момент структура каталога еще не устаканилась – читаем Recommended Project Directory Structure:

project
|-- application
|    |-- apis
|    |-- configs
|    |    `-- <em>application.ini</em>
|    |-- controllers
|    |    `-- helpers
|    |-- layouts
|    |    |-- filters
|    |    |-- helpers
|    |    `-- scripts
|    |-- models
|    |-- modules
|    |    `-- <module_name>
|    |         |-- controllers
|    |         |    `-- helpers
|    |         |-- views
|    |         |    |-- filters
|    |         |    |-- helpers
|    |         |    `-- scripts
|    |         `-- layouts
|    |              |-- filters
|    |              |-- helpers
|    |              `-- scripts
|    `-- <em>Bootstrap.php</em>
|-- data
|    |-- cache
|    |-- indexes
|    |-- locales
|    |-- logs
|    |-- sessions
|    `-- uploads
|-- docs
|-- library
|    `-- Zend
|-- public
|    |-- styles
|    |-- scripts
|    |-- images
|    |-- <em>.htaccess</em>
|    `-- <em>index.php</em>
`-- tests
     |-- application
     |    `-- <em>bootstrap.php</em>
     |-- library
     |    `-- <em>bootstrap.php</em>
     `-- <em>phpunit.xml</em>

Организация моделей в ZF

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

Zend Framework и SVN

Лучшая версия ZF лежит всегда в транке SVN’а – при этом snapshot’ы выкладываются не всегда адекватные, по этой причине лучше настроить экспорт для вашего проекта:

~$ svn propedit svn:externals library/
 Zend http://framework.zend.com/svn/framework/standard/trunk/library/Zend
 ZendX http://framework.zend.com/svn/framework/extras/trunk/library/ZendX

~$ svn propedit svn:externals lpublic/scripts/
 dojo http://svn.dojotoolkit.org/src/dojo/trunk/
 dijit http://svn.dojotoolkit.org/src/dijit/trunk/
 dojox http://svn.dojotoolkit.org/src/dojox/trunk/

Zend_Application и Zend_Bootstrap

Подключаем namespace для Autoloader’a
В официальной документации нет описания по добавлению неймспейсов посредством ini файла, исправляем:

; папка Core находится в library и включена в include_path
autoloadernamespaces[] = Core

Подключаем кастомные плагины для ресурсов (на примере класса Core_Resource_View)

Код конфигурационного файла application.ini:

; прописываем путь - Core_Resource - префикс имени класса
pluginPaths.Core_Resource = APPLICATION_PATH "/resources"
; инициализируем ресурс (хотя бы таким способом)
resources.view[] =
; передаем параметры
resources.view.title = "My Application"
resources.view.encoding = "UTF-8"

Код плагина View можете найти в официальной документации: Zend_Application: Examples

Прописываем плагины для FrontController’a в application.ini

resources.frontController.plugins[] = "Core_Controller_Plugin_Layout"
resources.frontController.plugins[] = "Core_Controller_Plugin_ErrorHandler"

// если необходимо передать паарметры
// пока не работает, отслеживаем http://framework.zend.com/issues/browse/ZF-6704
resources.frontController.plugins.errorhandler.classname = "Zend_Controller_Plugin_ErrorHandler" 
resources.frontController.plugins.errorhandler.options.module = "system" 
resources.frontController.plugins.errorhandler.options.controller = "error" 
resources.frontController.plugins.errorhandler.options.action = "error" 

Это аналогично следующей записи в Bootstrap.php:

    /**
     * @return Zend_Application
     */
    protected function _initPlugins()
    {
        $bootstrap = $this->getApplication();
        if ($bootstrap instanceof Zend_Application) {
             $bootstrap = $this;
        }
        $bootstrap->bootstrap('FrontController');
        $front = $bootstrap->getResource('FrontController');

        $front->registerPlugin(new Core_Controller_Plugin_Layout());
        $front->registerPlugin(new Core_Controller_Plugin_ErrorHandler());

        return $bootstrap;
    }

Используем различные layout’ы для модулей

Создаем новый плагин Сore_Controller_Plugin_Layout (файл library/Core/Controller/Plugin/Layout.php):

class Core_Controller_Plugin_Layout extends Zend_Controller_Plugin_Abstract
{
       public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
       {
               $layout = Zend_Layout::getMvcInstance();
               // указываем путь к layout'ам
               $layout ->setLayoutPath(APPLICATION_PATH . '/modules/' . $request->getModuleName() . '/layouts/scripts');
       }
}

Примечание: неймспейс Core должен быть проинициализирован для автолоадера

Используем различные ErrorController’ы для модулей

Создаем новый плагин Сore_Controller_Plugin_ErrorHandler (файл library/Core/Controller/Plugin/ErrorHandler.php):

class Core_Controller_Plugin_ErrorHandler extends Zend_Controller_Plugin_Abstract
{
    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
    {
        $frontController = Zend_Controller_Front::getInstance();
        $errorPlugin     = $frontController->getPlugin('Zend_Controller_Plugin_ErrorHandler');
        $errorPlugin->setErrorHandlerModule($request->getModuleName());
    }
}

Примечание: неймспейс Core должен быть проинициализирован для автолоадера

Прописываем роуты в application.ini

Роут для перенаправления страниц вида “чего-то-там.html” на контроллер “pages”, экшен “index”, и именем запрашиваемой страницы в переменной “alias”:

; Page
resources.router.routes.page.type = "Zend_Controller_Router_Route_Regex"
resources.router.routes.page.route = "([a-z0-9\-]+)\.html"
resources.router.routes.page.defaults.module = default
resources.router.routes.page.defaults.controller = pages
resources.router.routes.page.defaults.action = index
resources.router.routes.page.map.1 = alias

Работаем с конфигом application.ini

Многие привыкли работать с конфигом используя Zend_Regitry:

$configuration = new Zend_Config_Ini(
    APPLICATION_PATH . '/config/app.ini',
    APPLICATION_ENVIRONMENT
);
$registry = Zend_Registry::getInstance();
$registry->configuration = $configuration;

С версии 1.8 используем следующий синтаксис:

// В контроллере можно сделать так: 
$bootstrap = $this->getInvokeArg('bootstrap');
$configArray = $bootstrap->getOptions();
// либо так:
$this->getInvokeArg('bootstrap')->getOption('option');

// А если нужен экземпляр объекта Zend_Config, то надо добавить строчку:
$config = new Zend_Config($configArray);

Или, можно таки заюзать Zend_Registry и проинициализировать его в классе Bootstrap:

public function _initConfig()
{
      Zend_Registry::set('config', new Zend_Config($this->getOptions()));
}

Подсмотрено: Хитрости ZF1.8

Zend_Db

Инициализация профайлера посредством конфигурационного файла application.ini:

; говорим что нужно использовать профайлер
resources.db.params.profiler.enabled = true
; указываем желаемый профайлер
resources.db.params.profiler.class   = Zend_Db_Profiler_Firebug

Zend_Test

Приведу ссылки на полезные ресурсы по тестированию приложений на ZF:

P.S. Если Вам есть что добавить – пишите – думаю, многие будут Вам благодарны…

© Антон Шевчук 2007-2023