Programmer's Reference Guide
| Контроллеры действийAction Controllers |
Помощники действий
Введение
Помощники действий (action helpers) позволяют разработчикам добавлять функционал во время выполнения или по требованию в любые контроллеры действий, который расширяет Zend_Controller_Action. Помощники действий помогают снизить необходимость расширения абстрактного контроллера действий для того, чтобы добавить общий функционал в контроллер действий.
Есть несколько вариантов использования помощников действий.
Помощники действий используют брокерскую систему (brokerage system),
подобную той, которая используется в
Zend_View_Helpers и
Zend_Controller_Plugin.
Помощники действий (как и Zend_View_Helpers) могут быть
загружены и вызваны по требованию, либо инстанцироваться во время
запроса (начальной загрузки) или создания контроллера действий
(init()). Для того, чтобы лучше разобраться с этим, см. раздел
использования ниже.
Инициализация помощника
Помощник может быть инициализирован несколькими различными способами, выбор способа зависит от ваших нужд и от функционала, предоставляемого этим помощником.
Брокер помощников хранится как член $_helper класса
Zend_Controller_Action; используйте брокер для
получения или вызова помощников. Методы, предназначенные для этого,
включают в себя:
-
Явное использование
getHelper(). Просто передавайте ему имя, и будет возвращен объект помощника:<?php $flashMessenger = $this->_helper->getHelper('FlashMessenger'); $flashMessenger->addMessage('We did something in the last request'); -
Используйте функционал метода
__get()брокера помощников и извлекайте помощника так же, как если бы он был свойством этого брокера.<?php $flashMessenger = $this->_helper->FlashMessenger; $flashMessenger->addMessage('We did something in the last request'); -
И наконец, большинство помощников действий реализует метод
direct(), который будет вызывать особый, используемый по умолчанию метод в помощнике. Например, в случаеFlashMessengerбудет вызван методaddMessage():<?php $this->_helper->FlashMessenger('We did something in the last request');
Замечание: Все примеры выше функционально эквивалентны.
Вы можете также явно инстанцировать помощников. Вы можете захотеть сделать это, если используете помощника вне контроллера действий, или если хотите передавать помощника брокеру для использования в любых действиях. Инстанцирование производится так же, как и для любого другого класса PHP.
Брокер помощников
Zend_Controller_Action_HelperBroker управляет
регистрацией объектов помощников и путей к помощникам, а также
извлечением помощников по требованию.
Для того, чтобы зарегистрировать помощника через брокер, используйте
addHelper:
<?php
Zend_Controller_Action_HelperBroker::addHelper($helper);
Конечно, инстанцирование и передача помощников брокеру отнимают
некоторое время и ресурсы, поэтому существуют два метода для
некоторой автоматизации: addPrefix() и
addPath().
-
addPrefix()принимает префикс класса и использует его для определения пути, по которому определен класс помощника. Подразумевается, что префикс следует соглашениям по именованию классов Zend Framework.<?php // Добавление помощников, начинающихся с My_Action_Helpers в My/Action/Helpers/ Zend_Controller_Action_HelperBroker::addPrefix('My_Action_Helpers'); -
addPath()принимает директорию в качестве первого аргумента и префикс класса в качестве второго (по умолчанию это 'Zend_Controller_Action_Helper'). Это позволяет вам поставить в соответствие определенным директориям собственные префиксы классов.<?php // Добавление помощников, начинающихся с Helper в Plugins/Helpers/ Zend_Controller_Action_HelperBroker::addPath('./Plugins/Helpers', 'Helper');
Поскольку эти методы статические, то они могут вызываться из любого места в цепочке контроллеров для динамического добавления помощников, когда необходимо.
Для определения того, есть ли помощник в брокере, используйте
hasHelper($name), где $name - короткое имя помощника (без префикса):
<?php
// Проверка, зарегистрирован ли в брокере помощник 'redirector'
if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
echo 'Помощник Redirector зарегистрирован';
}
Наконец, для удаления зарегистрированного помощника из брокера,
используйте removeHelper($name), где $name
- короткое имя помощника (без префикса):
<?php
// Удаление помощника 'redirector' из брокера, помещенное в условную конструкцию
if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
Zend_Controller_Action_HelperBroker::removeHelper('redirector')
}
Встроенные помощники действий
Zend Framework по умолчанию включает в себя три помощника действий:
FlashMessenger для управления мгновенными сообщениями,
Redirector, предоставляющий различные реализации
перенаправления на внутренние и внешние страницы из вашего
приложения, и ViewRenderer для автоматизации процесса
настройки объекта вида в ваших контроллерах и рендеринга видов.
FlashMessenger
Введение
Помощник FlashMessenger позволяет передавать сообщения,
которые нужно показать пользователю при следующем запросе.
Для хранения сообщений до следующего запроса
FlashMessenger использует
Zend_Session_Namespace . Как правило, лучше всего
использовать тот Zend_Session или
Zend_Session_Namespace, который вы инициализировали с
помощью Zend_Session::start() в файле загрузки.
(За более подробной информацией об использовании см.
Zend Session).
Базовый пример использования
Пример использования ниже демонстрирует самые основы использования
мессенджера. Когда вызывается действие /some/my, оно
добавляет мгновенное сообщение "Record Saved!". Последующий запрос к
действию /some/my-next-request получит это сообщение
(и удалит его).
<?php
class SomeController extends Zend_Controller_Action
{
/**
* FlashMessenger
*
* @var Zend_Controller_Action_Helper_FlashMessenger
*/
protected $_flashMessenger = null;
public function init()
{
$this->_flashMessenger = $this->_helper->getHelper('FlashMessenger');
$this->initView();
}
public function myAction()
{
/**
* default method of getting Zend_Controller_Action_Helper_FlashMessenger
* instance on-demand
*/
$this->_flashMessenger->addMessage('Record Saved!');
}
public function myNextRequestAction()
{
$this->view->messages = $this->_flashMessenger->getMessages();
$this->render();
}
}
Redirector
Введение
Помощник Redirector позволяет использовать объект
redirector для удовлетворения нужд приложения в перенаправлении на
новые URL. Он дает многие преимущества по сравнению с методом
_redirect(), такие, как возможность предварительной
конфигурации поведения на стороне сайта в объекте redirector или
использование встроенного интерфейса
goto($action, $controller, $module, $params), подобного
интерфейсу Zend_Controller_Action::_forward().
Redirector имеет набор методов, которые могут
использоваться для воздействия на поведение при перенаправлении:
-
setCode()может использоваться для установки кода ответа HTTP, используемого при перенаправлении. -
setExit()может использоваться для установки принудительного вызоваexit()после перенаправления. По умолчанию он установлен в true. -
setGoto()может использоваться для установки URL, используемого по умолчанию (когда методуgoto()не был передан URL). Использует интерфейсZend_Controller_Action::_forward(): setgoto($action, $controller = null, $module = null, array $params = array()); -
setGotoRoute()может использоваться для установки URL, основываясь на зарегистрированном маршруте. Передавайте массив пар ключ/значение и имя маршрута, из них будет собран URL в соответствии с типом и определением маршрута. -
setGotoUrl()может использоваться для установки URL, используемого по умолчанию (когда методуgotoUrl()не был передан URL). Принимает только одну строку URL. -
setPrependBase()может использоваться для добавления базового URL объекта запроса в начало URL, заданного через методыsetGotoUrl(),gotoUrl(), илиgotoUrlAndExit(). -
setUseAbsoluteUri()может использоваться для принужденияRedirector-а использовать абсолютные URI при произведении перенаправления. Когда эта опция установлена, то используются значения$_SERVER['HTTP_HOST'],$_SERVER['SERVER_PORT']и$_SERVER['HTTPS']для формирования полного URI к URL, определенному одним из методов перенаправления. Эта опция по умолчанию отключена, но может быть включена по умолчанию в последующих релизах.
Кроме того, в Redirector есть различные методы, выполняющие текущие перенаправления:
-
goto()используетsetGoto()(интерфейс, подобный_forward()) для построения URL или произведения перенаправления. -
gotoRoute()используетsetGotoRoute()для построения URL и произведения перенаправления. -
gotoUrl()используетsetGotoUrl()(строка URL) для построения URL и произведения перенаправления.
Наконец, можно в любое время получить текущий URL для
перенаправления, используя getRedirectUrl().
Базовые примеры использования
Пример #1 Опции настройки
В этом примере переопределяются несколько опций, включая настройку код HTTP статуса, используемого при перенаправлении ('303'), и определение URL, используемого по умолчанию при перенаправлении.
<?php
class SomeController extends Zend_Controller_Action
{
/**
* Редиректор - определен для полноты кода
*
* @var Zend_Controller_Action_Helper_Redirector
*/
protected $_redirector = null;
public function init()
{
$this->_redirector = $this->_helper->getHelper('Redirector');
// Установка опций по умолчанию для редиректора
// Поскольку объект зарегистрирован в брокере помощников, то эти опции
// будут действительными для всех последующих действий
$this->_redirector->setCode('303')
->setExit(false)
->setGoto("this-action", "some-controller");
}
public function myAction()
{
/* делаем что-то */
// Перенаправление на ранее зарегистрированный URL и
// завершение выполнения:
$this->_redirector->redirectAndExit();
return; // никогда не будет достигнуто
}
}
}
Пример #2 Использование по умолчанию
Этот пример предполагает, что используются значения по
умолчанию, это означает, что после любых перенаправлений будет
производиться выход exit().
<?php
// АЛЬТЕРНАТИВНЫЙ ПРИМЕР
class AlternativeController extends Zend_Controller_Action
{
/**
* Редиректор - определен для полноты кода
*
* @var Zend_Controller_Action_Helper_Redirector
*/
protected $_redirector = null;
public function init()
{
$this->_redirector = $this->_helper->getHelper('Redirector');
}
public function myAction()
{
/* делаем что-то */
$this->_redirector->gotoUrl('/my-controller/my-action/param1/test/param2/test2');
// это место никогда не будет достигнуто,
// т.к. по умолчанию производится переход и завершение выполнения
return;
}
}
Пример #3 Использование интерфейса _forward() для goto()
Метод goto() копирует интерфейс метода
Zend_Controller_Action::_forward(). Основное
отличие состоит в том, что он строит URL из переданных
параметров и использует формат
:module/:controller/:action/* маршрутизатора по
умолчанию. Затем он производит перенаправление вместо добавления
действия в цепочку.
<?php
class ForwardController extends Zend_Controller_Action
{
/**
* Редиректор - определен для полноты кода
*
* @var Zend_Controller_Action_Helper_Redirector
*/
protected $_redirector = null;
public function init()
{
$this->_redirector = $this->_helper->getHelper('Redirector');
}
public function myAction()
{
/* Делаем что-то */
// Перенаправление на действие 'my-action' контроллера 'my-controller'
// в текущем модуле с использованием параметров param1 => test и
// param2 => test2
$this->_redirector->goto('my-action', 'my-controller', null, array('param1' => 'test', 'param2' => 'test2'));
}
}
Пример #4 Использование маршрута с gotoRoute()
Следующий пример использует метод assemble()
маршрута для
создания URL, основанного на переданном ассоциативном массиве
параметров. Этот пример предполагает, что были зарегистрирован
следующий маршрут:
<?php
$route = new Zend_Controller_Router_Route(
'blog/:year/:month/:day/:id',
array('controller' => 'archive', 'module' => 'blog', 'action' => 'view')
);
$router->addRoute('blogArchive', $route);
При заданном массиве, в котором year (год), month (месяц), и day
(день) установлены в 2006, 4 и 24 соответственно, будет построен
URL /blog/2006/4/24/42.
<?php
class BlogAdminController extends Zend_Controller_Action
{
/**
* Редиректор - определен для полноты кода
*
* @var Zend_Controller_Action_Helper_Redirector
*/
protected $_redirector = null;
public function init()
{
$this->_redirector = $this->_helper->getHelper('Redirector');
}
public function returnAction()
{
/* делаем что-то */
// Перенаправление в архив блога. Строит URL
// /blog/2006/4/24/42
$this->_redirector->gotoRoute(
array('year' => 2006, 'month' => 4, 'day' => 24, 'id' => 42),
'blogArchive'
);
}
}
ViewRenderer
Введение
Помощник ViewRenderer предназначен для решения
следующих задач:
-
Устранение необходимости инстанцирования объектов вида внутри контроллеров; объекты вида будут автоматически регистрироваться вместе с контроллером.
-
Автоматическая установка путей ко скриптам вида, помощникам и фильтрам, определяемая текущим модулем, и автоматическое присоединение имени текущего модуля в качестве префикса имен классов помощников и фильтров.
Создание глобально доступного объекта вида для всех запускаемых контроллеров и действий.
Возможность для разработчиков устанавливать используемые по умолчанию опции рендеринга вида для всех контроллеров.
Добавление возможности автоматического рендеринга скрипта вида, не требующего от разработчика каких-либо действий.
Возможность для разработчиков создавать собственные спецификации базового пути вида и путей ко скриптам видов.
Замечание: Если вы вручную производите
_forward(), перенаправление илиrender, то авторендеринг не будет произведен, поскольку выполнение любых этих операций говорит помощникуViewRenderer, что вы определили свой собственный вывод.
Замечание:
ViewRendererвключен по умолчанию. Вы можете отключить его через параметр фронт-контроллераnoViewRenderer($front->setParam('noViewRenderer', true)) или посредством удаления помощника из стека брокера помощников (Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer')).
Если вы хотите изменить настройкиViewRendererдо начала диспетчеризации, то можете сделать это двумя способами:
Инстанцировать, зарегистрировать свой объект
ViewRenderer, и затем передать его брокеру помощников:<?php $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer(); $viewRenderer->setView($view) ->setViewSuffix('php'); Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);Инициализировать и/или извлечь по запросу объект
ViewRendererчерез брокер помощников:<?php $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); $viewRenderer->setView($view) ->setViewSuffix('php');
API
В самом базовом его использовании вы просто инстанцируете
ViewRenderer и передаете его брокеру помощников.
Наиболее легким способом его инстанцирования и регистрации является
использование метода getStaticHelper() брокера
помощников:
<?php
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
Во время инстанцирования контроллера действий производится вызов
ViewRenderer для инстанцирования объекта вида. Каждый
раз, когда инстанцируется контроллер, вызывается метод
init() помощника ViewRenderer, что
приводит к установке свойства $view данного контроллера
действий и вызову метода addScriptPath() с путем
относительно текущего модуля; он будет вызван с префиксом класса,
соответствующим имени текущего модуля, что эффективно разделяет
пространства имен всех классов помощников и фильтров, которые вы
определили для этого модуля.
Каждый раз, когда вызывается postDispatch(), он будет
вызывать render() для текущего действия.
В качестве примера рассмотрим следующий класс:
<?php
// Класс контроллера, модуль foo:
class Foo_BarController extends Zend_Controller_Action
{
// Рендеринг bar/index.phtml по умолчанию;
// не требуется производить какие-либо операции
public function indexAction()
{
}
// Рендеринг bar/populate.phtml с переменной 'foo', установленной в 'bar'.
// Поскольку объект вида определен в preDispatch(), то он всегда доступен.
public function populateAction()
{
$this->view->foo = 'bar';
}
}
...
// в одном из ваших скриптов вида:
<?php $this->foo(); // call Foo_View_Helper_Foo::foo()
ViewRenderer также определяет несколько аксессоров для
того, чтобы можно было устанавливать и получать опции видов:
-
setView($view)позволяет установить объект вида дляViewRenderer. Объект сохраняется в открытом свойстве$viewкласса. -
setNeverRender($flag = true)может использоваться для отключения или включения авторендеринга глобально, т.е. для всех контроллеров. Если установлен вtrue, тоpostDispatch()не будет автоматически вызыватьrender()в текущем контроллере.getNeverRender()возвращает текущее значение. -
setNoRender($flag = true)может использоваться для отключения или включения авторендеринга. Если установлен вtrue, тоpostDispatch()не будет автоматически вызыватьrender()в текущем контроллере. Эта установка сбрасывается каждый раз во время вызоваpreDispatch()(т.е. нужно устанавливать этот флаг для каждого контроллера, для которого вы не хотите производить авторендеринг).getNoRender()возвращает текущее значение. -
setNoController($flag = true)может использоваться для того, чтобы указатьrender(), чтобы он не искал скрипт вида в поддиректории с именем контроллера (что является поведением по умолчанию).getNoController()возвращает текущее значение. -
setNeverController($flag = true)является аналогомsetNoController(), но работает на глобальном уровне - т.е. он не будет сбрасываться с каждым обработанным действием.getNeverController()возвращает текущее значение. -
setScriptAction($name)может использоваться для того, чтобы указать скрипт действия для рендеринга.$nameдолжен быть именем скрипта без суффикса (и без поддиректории контроллера, за исключением того случая, когда включенnoController). Если не задан, то ищется скрипт вида с именем, аналогичным имени действия в объекте запроса.getScriptAction()возвращает текущее значение. -
setResponseSegment($name)может использоваться для указания того, в какой именованный сегмент объекта ответа следует сохранить результат рендеринга. Если не указан, то выходные данные сохраняются в сегменте, используемом по умолчанию.getResponseSegment()возвращает текущее значение. -
initView($path, $prefix, $optionsможет вызываться для указания базового пути вида, префикса классов помощников и фильтров, опций помощникаViewRenderer. Вы можете передавать любые из следующих флагов:neverRender,noRender,noController,scriptActionиresponseSegment. -
setRender($action = null, $name = null, $noController = false)позволяет установитьscriptAction,responseSegment, илиnoControllerза один проход.direct()является псевдонимом для этого метода, что дает возможность легко вызывать этот метод из вашего контроллера.// Рендеринг 'foo' вместо текущего скрипта вида $this->_helper->viewRenderer('foo'); // Рендеринг form.phtml в сегмент ответа 'html' в обход // поддиректории: $this->_helper->viewRenderer('form', 'html', true);Замечание:
setRender()иdirect()в действительности не производят рендеринг скрипта вида, а устанавливают закрытые свойства помощника, которыеpostDispatch()иrender()будут использовать при рендеринге скрипта вида.
Конструктор позволяет опционально передать объект вида и опции
ViewRenderer. Он принимает те же флаги, что и
initView():
$view = new Zend_View(array('encoding' => 'UTF-8'));
$options = array('noController' => true, 'neverRender' => true);
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view, $options);
ViewRenderer имеет несколько дополнительных методов для
создания пользовательских спецификаций пути, используемых для
определения базового пути вида, добавляемого в объект вида, и пути к
определенному скрипту вида, используемого при автоматическом
определении скрипта вида для рендеринга. Все эти методы принимают
одну или более метку заполнения:
-
:moduleDirссылается на текущую базовую директорию модуля (по соглашению это директория, родительская по отношению к директории контроллеров модуля). -
:moduleссылается на имя текущего модуля. -
:controllerссылается на имя текущего контроллера. -
:actionссылается на имя текущего действия. -
:suffixссылается на суффикс скрипта вида (который может быть установлен черезsetViewSuffix()).
Методы для управления спецификациями пути:
-
setViewBasePathSpec($spec)позволяет изменить спецификацию пути, используемую для определения базового пути, добавляемого в объект вида. По умолчанию используется спецификация:moduleDir/views. Вы можете в любое время получить текущую спецификацицию, используя методgetViewBasePathSpec(). -
setViewScriptPathSpec($spec)позволяет изменить спецификацию пути, используемую для определения пути к отдельному скрипту вида (без базового пути скрипта вида). По умолчанию используется спецификация:controller/:action.:suffix. Вы можете в любое время получить текущую спецификацию, используя методgetViewScriptPathSpec(). -
setViewScriptPathNoControllerSpec($spec)позволяет изменить спецификацию пути, используемую для определения пути к отдельному скрипту вида, когда действуетnoController(без базового пути скрипта вида). По умолчанию используется спецификация:action.:suffix. Вы можете в любое время получить текущую спецификацию, используя методgetViewScriptPathNoControllerSpec().
Последними элементами в API ViewRenderer-а являются
методы для собственно определения путей ко скриптам вида и
рендеринга видов. Эти методы включают в себя:
-
renderScript($script, $name)позволяет производить рендеринг скрипта по указанному пути, опционально в заданный именованный сегмент. Если используется этот метод, тоViewRendererне производит автоматическое определение имени скрипта, вместо этого он напрямую передает аргумент$scriptметодуrender()объекта вида.Замечание: После того, как был произведен рендеринг вида в объект ответа, устанавливается
noRenderдля предотвращения случайного повторного рендеринга того же скрипта вида.Замечание: По умолчанию
Zend_Controller_Action::renderScript()вызывает методrenderScript()помощникаViewRenderer.
-
getViewScript($action, $vars)создает путь ко скрипту вида, основываясь на переданном действии $action и/или переменных, переданных в $vars. Этот массив может включать в себя ключи спецификаций пути ('moduleDir', 'module', 'controller', 'action' и 'suffix'). Если переменная была передана, то она будет использована, иначе будут использоваться значения из текущего запроса.getViewScript()будет использоватьviewScriptPathSpec, либоviewScriptPathNoControllerSpec, в зависимости от установки флагаnoController.Разделители слов в именах модуля, контроллера или действия будут заменены на тире ('-'). Таким образом, если вы имеете контроллер с именем 'foo.bar' и действие 'baz:bat', то при использовании спецификации пути по умолчанию результатом будет путь 'foo-bar/baz-bat.phtml' ко скрипту вида.
Замечание: По умолчанию
Zend_Controller_Action::getViewScript()вызывает методgetViewScript()помощникаViewRenderer.
-
render($action, $name, $noController)сначала проверяет, были ли переданы параметры$nameили$noController, и если были переданы, то устанавливает соответствующие флаги (responseSegment и noController соответственно) в ViewRenderer. Затем он передает параметр$action(если есть) методуgetViewScript(). Наконец, он передает полученный путь ко скрипту вида методуrenderScript().Замечание: Следует помнить о побочных эффектах использования render(): значения, передаваемые для имени сегмента ответа и флага noController, сохраняются в объекте. Кроме этого, по окончании рендеринга будет установлен noRender.
Замечание: По умолчанию
Zend_Controller_Action::render()вызывает методrender()помощникаViewRenderer.
-
renderBySpec($action, $vars, $name)позволяет передавать переменные спецификации пути для определения создаваемого пути ко скрипту вида. Он передает$actionи$varsметодуgetScriptPath(), затем передает полученный путь и$nameметодуrenderScript().
Примеры базового использования
Пример #5 Базовое использование
В самом базовом использовании вы просто инициализируете и
регистрируете помощник ViewRenderer через брокер
помощников в своем файле загрузки и затем устанавливаете
переменные в своих методах действий.
<?php
// В вашем файле загрузки:
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
...
<?php
// Модуль 'foo', контроллер 'bar':
class Foo_BarController extends Zend_Controller_Action
{
// По умолчанию производится рендеринг bar/index.phtml;
// дополнительные действия не требуются
public function indexAction()
{
}
// Рендеринг bar/populate.phtml с переменной 'foo', установленной в 'bar'.
// Поскольку объект вида был определен в preDispatch(), то он уже
// доступен для использования.
public function populateAction()
{
$this->view->foo = 'bar';
}
// Ничего не рендерится, т.к. производится переход на другое действие;
// это другое действие может производить рендеринг
public function bazAction()
{
$this->_forward('index');
}
// Ничего не рендерится, т.к. производится перенаправление по другому адресу
public function batAction()
{
$this->_redirect('/index');
}
}
Замечание: Соглашения по именованию: Разделители слов в именах контроллера и действия
Если имена вашего контроллера и действия состоят из нескольких слов, то диспетчер требует, чтобы в URL они были разделены определенными символами-разделителями слов и путей.ViewRendererпри создании путей заменяет все найденные в имени контроллера разделители путей действующим разделителем путей ('/') и все разделители слов - чертой ('-'). Таким образом, вызов действия/foo.bar/baz.batдолжен быть преобразован в вызов методаFooBarController::bazBatAction()вFooBarController.php, который в свою очередь произведет рендеринг скрипта видаfoo-bar/baz-bat.phtml. Вызов действия/bar_baz/baz-batдолжен быть преобразован в вызовBar_BazController::bazBatAction()вBar/BazController.php(обратите внимание на разделение путей), при этом производится рендерингbar/baz/baz-bat.phtml.
Во втором примере обратите внимание на то, что по-прежнему используется модуль по умолчанию, но из-за наличия разделителя путей получается имя контроллераBar_BazControllerв файлеBar/BazController.php.ViewRendererимитирует иерархию директорий контроллеров.
Пример #6 Отключение авторендеринга
Может потребоваться отключить авторендеринг для некоторых
действий или контроллеров - например, если вы хотите производить
вывод разного типа (XML, JSON и т.д.), или просто не хотите
ничего выводить. У вас есть два варианта - вы можете полностью
отключить авторендеринг (setNeverRender()), либо
отключить его для текущего действия
(setNoRender()).
<?php
// Класс контроллера baz, модуль bar:
class Bar_BazController extends Zend_Controller_Action
{
public function fooAction()
{
// Не производить авторендеринг в этом действии
$this->_helper->viewRenderer->setNoRender();
}
}
// Класс контроллера bat, модуль bar:
class Bar_BatController extends Zend_Controller_Action
{
public function preDispatch()
{
// Не производить авторендеринг во всех действиях этого контроллера
$this->_helper->viewRenderer->setNoRender();
}
}
Замечание: В большинстве случаев не имеет смысла глобально отключать авторендеринг (через
setNeverRender()), поскольку единственная выгода, которую вы получаете в этом случае от использованияViewRenderer- автоматическая установка объекта вида.
Пример #7 Выбор другого скрипта вида
Некоторые ситуации требуют, чтобы производился рендеринг скрипта
с именем, отличным от имени действия. Например, если у вас есть
контроллер, который имеет методы действий для добавления и
редактирования, они оба могут отображать один и тот же вид
'форма', хоть и с разным набором значений. Вы легко можете
изменить имя скрипта, используя методы
setScriptAction() и setRender(), или
вызывая помощника как метод - он произведет вызов метода
setRender().
<?php
// Класс контроллера bar, модуль foo:
class Foo_BarController extends Zend_Controller_Action
{
public function addAction()
{
// Рендерить 'bar/form.phtml' вместо 'bar/add.phtml'
$this->_helper->viewRenderer('form');
}
public function editAction()
{
// Рендерить 'bar/form.phtml' вместо 'bar/edit.phtml'
$this->_helper->viewRenderer->setScriptAction('form');
}
public function processAction()
{
// произведение валидации...
if (!$valid) {
// Рендерить 'bar/form.phtml' вместо 'bar/process.phtml'
$this->_helper->viewRenderer->setRender('form');
return;
}
// иначе продолжение обработки...
}
}
Пример #8 Модификация зарегистрированного объекта вида
А что, если вам нужно модифицировать объект вида - например,
изменить пути к помощникам или кодировку? Вы можете делать это
как через модификацию объекта вида, установленного в вашем
контроллере, так и через извлечение объекта вида из
ViewRenderer, оба они являются ссылками на один и
тот же объект.
<?php
// Класс контроллера bar, модуль foo:
class Foo_BarController extends Zend_Controller_Action
{
public function preDispatch()
{
// Изменение кодировки вида
$this->view->setEncoding('UTF-8');
}
public function bazAction()
{
// Получение объекта вида и указание 'htmlspecialchars'
// в качестве функции для экранирования
$view = $this->_helper->viewRenderer->view;
$view->setEscape('htmlspecialchars');
}
}
Примеры продвинутого использования
Пример #9 Изменение спецификаций пути
В некоторых случаях вы можете решить, что спецификации пути, используемые по умолчанию, не соответствуют требованиям вашего сайта. Например, вы можете захотеть иметь одно дерево шаблонов, к которому можно давать доступ дизайнерам (что довольно типично, когда, например, используется » Smarty). В таком случае вы можете захотеть задать жесткую спецификацию базового пути вида и создать альтернативную спецификацию для собственно путей ко скриптам вида.
В рамках данного примера предположим, что базовый путь ко скриптам вида - '/opt/vendor/templates', и вы хотите, чтобы обращение ко скриптам вида производилось по схеме ':moduleDir/:controller/:action.:suffix'. Также предположим, что если флаг noController установлен, то нужно, чтобы использовался верхний уровень вместо поддиректории (':action.:suffix'). И наконец, вы хотите использовать 'tpl' в качестве суффикса имени скрипта вида.
<?php
/**
* В вашем файле загрузки:
*/
// Другая реализация вида
$view = new ZF_Smarty();
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
$viewRenderer->setViewBasePathSpec('/opt/vendor/templates')
->setViewScriptPathSpec(':module/:controller/:action.:suffix')
->setViewScriptPathNoControllerSpec(':action.:suffix')
->setViewSuffix('tpl');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
Пример #10 Рендеринг нескольких скриптов вида из одного действия
Иногда бывает нужно произвести рендеринг нескольких скриптов
вида из одного действия. Решение очевидное - просто
сделайте несколько вызовов метода render():
<?php
class SearchController extends Zend_Controller_Action
{
public function resultsAction()
{
// Предполагается, что $this->model - текущая модель
$this->view->results = $this->model->find($this->_getParam('query', '');
// render() по умолчанию использует ViewRenderer
// Рендеринг формы поиска и затем результатов поиска
$this->render('form');
$this->render('results');
}
public function formAction()
{
// Ничего не делается. ViewRenderer автоматически производит
// рендеринг скрипта вида
}
}
Написание собственных помощников
Помощники действий расширяют
Zend_Controller_Action_Helper_Abstract, абстрактный
класс, который дает базовый интерфейс и функционал, требуемый
брокером помощников. Он включает в себя следующие методы:
-
setActionController()используется для установки текущего контроллера действий. -
init(), запускаемый брокером при инстанцировании, может использоваться для запуска инициализации в помощнике. Это может быть полезным для переустановки состояния, когда несколько контроллеров используют один и тот же помощник в цепочке действий. -
preDispatch()запускается до запуска действия. -
postDispatch()запускается тогда, когда запущенное действие завершило свое выполнение - даже если плагинpreDispatch()пропустил это действие. Полезно в основном для очистки. -
getRequest()возвращает текущий объект запроса. -
getResponse()возвращает текущий объект ответа. -
getName()возвращает имя помощника. Он извлекает ту часть имени класса, которая следует после последнего символа подчеркивания, иначе возвращается полное имя класса. Например, если класс называетсяZend_Controller_Action_Helper_Redirector, то он вернетZend_Controller_Action_Helper_Redirector,Redirector, а если класс называетсяFooMessageто он просто вернет свое полное имя.
Вы можете опционально добавить метод direct() в свой
класс помощника. Если он определен, то это позволит вам обращаться к
помощнику как к методу брокера помощников, этим обеспечивается
легкое, единоразовое использование помощника. Например,
redirector
определяет direct() как псевдоним метода
goto(), что позволяет использовать помощника следующим
образом:
<?php
// Перенаправление на /blog/view/item/id/42
$this->_helper->redirector('item', 'view', 'blog', array('id' => 42));
Метод брокера помощников __call() ищет помощника с
именем redirector, затем смотрит, имеет ли помощник
определенный метод direct, и, если есть, вызывает его с
переданными аргументами.
Создав собственный класс помощника, вы можете предоставить доступ к нему, как описано в разделах выше.
| Контроллеры действийAction Controllers |
Select a Version
Languages Available
Components
Search the Manual
Navigation
- Руководство разработчика
- Руководство разработчика
- Zend_Controller
- Zend_Controller - Быстрый стартZend_Controller Quick Start
- Основы Zend_ControllerZend_Controller Basics
- Фронт-контроллер
- Объект запросаThe Request Object
- Стандартный маршрутизатор: Zend_Controller_Router_RewriteThe Standard Router: Zend_Controller_Router_Rewrite
- ДиспетчерThe Dispatcher
- Контроллеры действийAction Controllers
- Помощники действийAction Helpers
- Объект ответаThe Response Object
- ПлагиныPlugins
- Использование определенной соглашением модульной структуры директорийUsing a Conventional Modular Directory Structure
- ИсключенияMVC Exceptions
- Переход с предыдущих версийMigrating from Previous Versions
