Приветствую вас.
Это вторая статья серии, посвящённой основам Zend Framework.
Первая статья серии
В этой статье вы более подробно ознакомитесь с Zend_Controller и научитесь использовать Zend_Controller_Router_Rewrite.

Часть 3. Подробнее о Zend_Controller

1
2
3
4
5
6
7
8
9
10
11
12
//начальное объявление констант
//позволяет добиться гибкости именования и размещения основных каталогов
define('ROOTPATH', $_SERVER['DOCUMENT_ROOT'] . '/..');
define('HOMEPATH', ROOTPATH . '/public_html');
define('LIBPATH', ROOTPATH . '/lib');

//устанавливаем каталог библиотек корневым и подключаем Zend_Controller
set_include_path(LIBPATH . '/library');
require_once('Zend/Controller/Front.php');

//собственно, запуск выполнения нужного действия (action)
Zend_Controller_Front::run(LIBPATH . '/application/controllers');

Как вы видите, запускает Zend_Controller единственный метод – run, которому мы передаём путь до каталога контроллеров. Довольно просто и удобно, но этим возможности Zend_Controller_Front не ограничиваются. Мы можем явно инстанцировать Zend_Controller_Front и управлять им при помощи публичных методов и расширять его возможности плагинами и обработчиками. Одним словом, настраиваемость Zend_Controller поражает воображение :)
Zend_Controller_Front реализует паттерн проектирования Одиночка (Singleton), о чём мы поговорим позже. Сейчас нам важно одно – инстанцирование класса при помощи оператора “new” невозможно. Единственный способ получить экземпляр этого класса – вызвать статический метод Zend_Controller_Front::getInstance(). Если вы не знаете, что делает паттерн Singleton – полезно будет ознакомиться с этим, благо в интернете множество материала на эту тему.
Вот пример расширенного использования Zend_Controller_Front:

1
2
3
$front = Zend_Controller_Front::getInstance();
$front->setControllerDirectory(LIBPATH . '/application/controllers');
$front->dispatch();

Ничем особенным этот код от вызова метода Zend_Controller_Front::run() не отличается, но даёт нам простор для настройки.
Есть ещё один полезный инструмент Zend_Controller_Front: параметры. Управление параметрами происходит при помощи следующих методов:

  • setParam($name, $value) – устанавливает параметру $name значение $value
  • setParams(array $params) – устанавливает параметры с помощью ассоциативного массива
  • getParam($name) – получаем значение параметра
  • getParams() – получаем ассоциативный массив со всеми параметрами
  • clearParams($name = null) – удаляем один параметр (если имя параметра не передано – удаляем все параметры)

Что же такое особенное нам позволяют сделать параметры? В Zend_Controller встроено несколько параметров

  • useDefaultControllerAlways – для всех URL, контроллер и/или действие для которых не найдены, используется контроллер по умолчанию (IndexController)
  • disableOutbutBuffering – отключает встроенную буферизацию вывода (по умолчанию включена)
  • noViewRenderer – отключает помощник ViewRenderer (по умолчанию включен)
  • noErrorHandler – отключает плагин ErrorHandler (по умолчанию включен)

О последних двух параметрах (ViewRenderer и ErrorHandler) я расскажу вам несколько позже.
Расширим наш код отключением помощника ViewRenderer:

1
2
3
4
$front = Zend_Controller_Front::getInstance();
$front->setControllerDirectory(LIBPATH . '/application/controllers');
$front->setParam('noViewRenderer', true);
$front->dispatch();

Часть 4. Zend_Controller_Router_Rewrite

Router_Rewrite – используемый по умолчанию маршрутизатор Zend_Controller. По сути, маршрутизатор разбивает URL на части и определяет, какой контроллер и какое действие в нём заданы.
Для того, чтобы сработал Router_Rewrite, необходимо создать в каталоге с index.php файл .htaccess с текстом:

1
2
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php

Указанное нами правило mod_rewrite будет переадресовывать все запросы, не содержащие перечисленные расширения, файлу index.php. Это позволит классу Zend_Controller_Router_Rewrite отловить и обработать эти запросы.
Добавим новый маршрут:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$front = Zend_Controller_Front::getInstance();
$front->setControllerDirectory(LIBPATH . '/application/controllers');
$router = $front->getRouter();
$router->addRoute(
    'user',
    new Zend_Controller_Router_Route(
        'user/:username',   //указываем URL
        array(
            'controller' => 'users',    //имя контроллера
            'action' => 'info',     //имя действия
            'username' => 'admin'   //значение по умолчанию
        )
    )
);
$front->dispatch();

Теперь при наборе URL http://site.ru/user/artemon выполнится контроллер Users, действие info. Если username не будет указан в URL, то ему присвоится значение по умолчанию ‘admin’ (см. предыдущий пример). Получить username мы сможем в нашем действии (infoAction), вызвав метод _getParam():

1
echo $this->_getParam('username');

Вот и всё. Основы Zend_Controller раскрыты, я надеюсь, достаточно для начала работы. Как я уже говорил, ничто не заменит вам документацию и API Zend Framework.
До скорых встреч!

14 Comments

  1. Markus says:

    Помогите! Нихрена не пойму где проблема!

    Fatal error: Uncaught exception ‘Zend_Controller_Dispatcher_Exception’ with message ‘Invalid controller specified (error)’ in /home/jaga/engenie/zend/libs/Zend/Controller/Dispatcher/Standard.php:249 Stack trace: #0 /home/jaga/engenie/zend/libs/Zend/Controller/Front.php(914): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #1 /home/jaga/public_html/index.php(21): Zend_Controller_Front->dispatch() #2 {main} thrown in /home/jaga/engenie/zend/libs/Zend/Controller/Dispatcher/Standard.php on line 249

  2. admin says:

    У вас в скрипте есть некая ошибка. По умолчанию в Zend_Controller включен свой обработчик ошибок, запускающий Error_Controller -> errorAction().
    Перечитайте мануал по Zend_Controller’у и проверьте свой скрипт на наличие ошибок.

  3. Markus says:

    Отрубил noViewRenderer и все заработало, но если честно непонял в чём суть ошибки. :(

  4. Markus says:

    вернее отрубил ViewRenderer

  5. Markus says:

    ошибка кстати ета вылазиет, если задан маршрут к контроллеру обработчика для которого нет.

  6. Markus says:

    туплю :)

  7. Роман says:

    Что за слово такое: инстацировать???

  8. admin says:

    Инстанцирование (англ. instantiation) — создание экземпляра класса. В отличие от слова «создание» применяется не к объекту, а к классу. То есть, говорят “создать экземпляр класса или инстанцировать класс”.

    За указание на опечатку спасибо, поправил.

  9. easter says:

    Прописал роутинг
    $defaultRoute = new Zend_Controller_Router_Route(‘:lang/:module/:controller/:action/’,
    array(‘lang’ => $temp,
    ‘module’ => $mod,
    ‘controller’ => $ctrl,
    ‘action’ => $action,
    );
    Не могу понять. Когда угл у меня например http://www.server.com/ru/controler/action/papam1/param2/param3
    ругается на то, что нет контролера param3
    Как заставить его все что после action считать параметрами?

  10. Сергей Митрошин says:

    ‘:lang/:module/:controller/:action/*’

  11. Сергей Митрошин says:

    Но в твоём случае это не поможет – в URLе ты пропустил указание модуля.
    А вообще про локализацию можешь почитать здесь:
    http://zend-framework.ru/forum/viewtopic.php?f=12&t=17

  12. easter says:

    ‘*’ не помогает
    попробовал вообще так
    $defaultRoute = new Zend_Controller_Router_Route(’*’,
    array(’lang’ => $temp,
    ‘module’ => $mod,
    ‘controller’ => $ctrl,
    ‘action’ => $action,
    );
    Сначала обрабовался, что заработало, но не тут то было.
    Неправильно стало определяться начало параметров (тоесть вместо ‘param1′ например ‘ram1′). Предположения есть почему так, но всеравно похоже на глюк фрэймвлрка.

  13. easter says:

    Пока перекрылся внутри контролера так:
    $http = new Zend_Controller_Request_Http();
    $tmp = explode(“/”, $http->getRequestUri());
    for ($i = 4; $i params[] = $tmp[$i];
    }
    Галимо конечно :(
    Если кто знает ответ, напишите плиз.

  14. easter says:

    блин парсер всё сожрал :( (сори, но превью тут нет)
    короче там в ‘for’ c 4 элемента до конца массива $tmp все заностся в массив параметров

Leave a Reply