Programmer's Reference Guide
| Исключения |
Переход с предыдущих версий
API компонент системы MVC претерпевал изменения со временем. Если вы начали использование Zend Framework с его ранних версий, то следуйте приведенным ниже рекомендациям по переносу вашего кода на новую архитектуру.
Переход с 1.6.x на 1.7.0 и более поздние версии
Изменения в интерфейсе диспетчера
Пользователи обратили наше внимание на тот факт, что
Zend_Controller_Action_Helper_ViewRenderer
использует не присутствующий в интерфейсе метод из
абстрактного класса диспетчера. Мы добавили
этот метод в интерфейс диспетчера для того,
чтобы гарантировать работу созданного вами диспетчера с
классами, входящими в поставку Zend Framework:
formatModuleName(): должен принимать необработанное имя контроллера (в том виде, в котором оно хранится в объекте запроса) и преобразовывать его в имя класса контроллера, наследующего отZend_Controller_Action.
Переход с 1.5.x на 1.6.0 и более поздние версии
Изменения в интерфейсе диспетчера
Пользователи обратили наше внимание на тот факт, что
Zend_Controller_Front и
Zend_Controller_Router_Route_Module используют
методы диспетчера, которые не определены в его интерфейсе.
Мы добавили следующие три метода в его интерфейс для того,
чтобы гарантировать работу созданного вами диспетчера с
классами, входящими в поставку Zend Framework:
getDefaultModule(): должен возвращать имя используемого по умолчанию модуля.getDefaultControllerName(): должен возвращать имя используемого по умолчанию контроллера.getDefaultAction(): должен возвращать имя используемого по умолчанию действия.
Переход с 1.0.x на 1.5.0 и более поздние версии
Хотя основной набор функциональных возможностей остался тем же, и все документированные возможности не претерпели изменений, есть одна недокументированная "возможность", которая была изменена.
При написании URL-ов, документированным способом написания имен действий в формате camelCase является использование разделителей слов. По умолчанию это '.' или '-', но они могут быть заменены на другие символы путем настройки диспетчера. Диспетчер внутри себя приводит имена действий к нижнему регистру и использует эти разделители слов для "пересборки" имен действий с использованием формата camelCase. Но из-за того, что функции PHP не чувствительны к регистру, вы могли по-прежнему писать URL-ы в формате camelCasе, и результатом был запуск тех же методов действий. Например, 'camel-cased' должен был преобразовываться диспетчером в 'camelCasedAction', а 'camelCased' - в 'camelcasedAction', но из-за нечувствительности PHP к регистру имен функций в обоих случаях будет произведен вызов одного и того же метода.
Это вызывало проблемы с ViewRenderer при определении имени скрипта вида. Документированный способ состоит в том, что все разделители слов преобразуются в тире, и слова приводятся к нижнему регистру. Это создает семантическую связь между действиями и скриптами видов, а нормализация гарантирует, что скрипты могут быть найдены. Тем не менее, если вызывается действие с именем 'camelCased' и благополучно обработано, то разделитель слов более не присутствует в имени, и ViewRenderer пытается вызвать другой скрипт вида - 'camelcased.phtml' вместо 'camel-cased.phtml'.
Некоторые разработчики полагались на эту незапланированную "возможность". Тем не менее, некоторые изменения в дереве 1.5.0, привели к тому, что ViewRenderer более не ищет такие пути; семантическая связь теперь усилена. Главное, диспетчер теперь чувствителен к регистру в именах действий. Это значит, что ссылка на действие через URL с использованием формата camelCase не будет приводить к вызову того же метода, что и с использованием разделителей слов (т.е. 'camel-casing').
Если получилось, что вы используете эту "возможность", то в имеете несколько вариантов решения:
Наилучший вариант: переименуйте ваши скрипты вида. Плюсы: будущая совместимость. Минусы: если вы имеете много скриптов вида, которые полагаются на старое, незапланированное поведение, то вам придется сделать много переименований.
-
Второй лучший вариант: ViewRenderer теперь делегирует определение скриптов вида инфлектору
Zend_Filter_Inflector; вы можете изменить правила инфлектора так, чтобы он более не разделял слова в имени действия знаком тире:$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); $inflector = $viewRenderer->getInflector(); $inflector->setFilterRule(':action', array( new Zend_Filter_PregReplace( '#[^a-z0-9' . preg_quote(DIRECTORY_SEPARATOR, '#') . ']+#i', '' ), 'StringToLower' ));Приведенный выше код изменит инфлектор таким образом, чтобы он более не разделял слова в имени действия знаком тире; вы можете также убрать фильтр 'StringToLower', если хотите, чтобы реальные имена скриптов вида тоже были в формате camelCase.
Если переименование скриптов вида слишком утомительно или требует много времени, то этот вариант будет наилучшим решением на тот период, пока вы не найдете время на переименование.
-
Менее желательное решение: Вы можете заставить диспетчер принимать имена действий в формате camelCase, установив новый флаг фронт-контроллера 'useCaseSensitiveActions':
$front->setParam('useCaseSensitiveActions', true);Это позволит вам использовать camelCase в URL-ах и они будут приводить к запуску тех действий, что и при использовании разделителей слов. Тем не менее, это будет означать, что исходная проблема может повлечь за собой другие; возможно, вам потребуется также использовать описанный выше второй вариант, чтобы все работало наверняка.
Также заметьте, что использование этого флага приведет к появлению предупреждения (notice) о том, что его использование не рекомендуется.
Переход с 0.9.3 на 1.0.0RC1 и более поздние версии
Основные изменения, появившиеся в 1.0.0RC1 - это добавление включенного по умолчанию плагина ErrorHandler и помощника действий ViewRenderer. Пожалуйста, прочитайте внимательно документацию к ним, чтобы понять, как они работают, и как они могут повлиять на работу ваших приложений.
Плагин ErrorHandler производит в методе
postDispatch() проверку на предмет исключений и
переход (forwarding) к определенному контроллеру-обработчику
исключений. Вы можете отключить его путем установки параметра
noErrorHandler во фронт-контроллере:
$front->setParam('noErrorHandler', true);
Помощник действий ViewRenderer автоматизирует
добавление вида в контроллеры действий и производит авторендеринг
скрипта вида, выбранного по текущему действию. Первая проблема, с
которой вы можете встретиться - у вас есть действия,
которые не производят рендеринг скриптов вида и не производят
переход или перенаправление, поскольку ViewRenderer
будет пытаться запустить скрипт вида, выбранного по имени действия.
Есть несколько стратегий, используя которые, вы можете обновить свой
код. В краткострочной перспективе решением может быть глобальное
отключение ViewRenderer во фронт-контроллере до
начала процесса диспетчеризации:
// $front является экземпляром Zend_Controller_Front
$front->setParam('noViewRenderer', true);
Но в долгосрочной перспективе это не лучшее решение, поскольку оно означает, что вам в будущем придется писать больше кода.
Когда вы будете готовы начать использование функционала
ViewRenderer, то необходимо проверить некоторые места в
коде контроллеров. Первое, просмотрите методы действий (методы,
заканчивающиеся на 'Action') и определите, что делает каждый метод.
Если не происходит ничего из следующего, то нужно произвести
изменения:
Вызов
$this->render()Вызов
$this->_forward()Вызов
$this->_redirect()Вызов помощника действий
Redirector
Наиболее легким способом будет отключение авторендеринга в данном методе:
$this->_helper->viewRenderer->setNoRender();
Если вы обнаружили, что ни один из методов действий не производит
рендеринг, переход или перенаправление, то, скорее всего, нужно
поместить эту строку в методы
preDispatch() или init():
public function preDispatch()
{
// отключение авторендеринга скриптов вида
$this->_helper->viewRenderer->setNoRender()
// ... еще код ..
}
Если вы вызываете render() и используете
определенную соглашением
модульную структуру директорий, то нужно
изменить свой код так, чтобы использовался авторендеринг:
-
Если производится рендеринг нескольких скриптов вида в одном действии, то не нужно ничего изменять.
-
Если производится простой вызов метода
render()без аргументов, то можете удалить соответствующие строки. -
Если вызывается
render()с аргументами и не производится впоследствии каких-либо действий или рендеринга нескольких скриптов вида, то можно заменить эти вызовы на чтение$this->_helper->viewRenderer().
На тот случай, если вы не используете определенную соглашением
модульную структуру директорий, есть набор методов для
установки базового пути к видам и спецификаций пути ко скрипту,
поэтому вы сможете и в этом случае использовать
ViewRenderer. Информацию об этих методах вы найдете в
документации
по ViewRenderer
Если вы используете объект вида из реестра, создали свой объект
вида, либо используете другие реализации встроенного, то может
потребоваться добавить этот объект в ViewRenderer. Это
легко можно сделать в любой момент времени.
-
До начала диспетчеризации экземпляра фронт-контроллера:
// Предполагается, что $view уже определен $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view); Zend_Controller_Action_HelperBroker::addHelper($viewRenderer); -
В любой точке процесса загрузки (bootstrap process):
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); $viewRenderer->setView($view);
Есть много способов модификации ViewRenderer, включая
установку других скриптов вида для рендеринга, определение замещений
для всех замещаемых элементов пути ко скрипту вида (включая
суффикс), выбор именованного сегмента ответа в качестве
используемого и др. Если вы не используете определенную соглашением
модульную структуру директорий, то можете ассоциировать с
ViewRenderer другие спецификации путей.
Рекомендуется адаптировать свой код для использования
ErrorHandler и ViewRenderer, так как
сейчас это лежащий в основе фреймворка функционал.
Переход с 0.9.2 на 0.9.3 и более поздние версии
В версии 0.9.3 были добавлены помощники действий (action helpers). Это изменение включает в себя удаление перечисленных ниже методов из-за того, что сейчас они инкапсулированы в помощнике перенаправлений (redirector action helper):
-
setRedirectCode(); используйтеZend_Controller_Action_Helper_Redirector::setCode(). -
setRedirectPrependBase(); используйтеZend_Controller_Action_Helper_Redirector::setPrependBase(). -
setRedirectExit(); используйтеZend_Controller_Action_Helper_Redirector::setExit().
Более подробную информацию о том, как извлекать и работать с объектами действий, читайте в документации по помощникам действий. Об установке опций перенаправления и альтернативных методах перенаправления читайте в документации по помощнику перенаправлений.
Переход с 0.6.0 на 0.8.0 и более поздние версии
Базовое использование компонент MVC не изменилось:
Zend_Controller_Front::run('/path/to/controllers');
Тем не менее, структура директорий была подвергнута пересмотру, некоторые компоненты были удалены, другие добавлены или переименованы. Изменения включают в себя следующее:
-
Zend_Controller_Routerудален в пользу использования Rewrite Router. -
Zend_Controller_RewriteRouterпереименован вZend_Controller_Router_Rewrite, теперь это стандартный маршрутизатор, поставляемый с фреймворком.Zend_Controller_Frontбудет использовать его по умолчанию, если не был установлен другой маршрутизатор. -
Добавлен новый класс маршрута для использования с Rewrite Router -
Zend_Controller_Router_Route_Module. Он включает в себя маршрут по умолчанию, используемый MVC, и поддерживает модули контроллеров. -
Zend_Controller_Router_StaticRouteпереименован вZend_Controller_Router_Route_Static. -
Zend_Controller_Dispatcherпереименован вZend_Controller_Dispatcher_Standard. -
Аргументы метода
Zend_Controller_Action::_forward()изменились. Его сигнатура теперь:final protected function _forward($action, $controller = null, $module = null, array $params = null);$action- обязательный аргумент. Если не был определен контроллер, то предполагается, что вызывается действие в текущем контроллере.$moduleвсегда игнорируется, если не определен контроллер. Все переданные в аргументе$paramsпараметры будут добавлены в объект запроса. Если вы не запрашиваете контроллер или модуль, но нужно передать параметры, то просто укажите null на месте соответствующих аргументов.
Переход с 0.2.0 и более ранних версий на 0.6.0
Базовое использование компонент системы MVC не изменилось, следующий код будет корректно выполняться и в версии 0.6.0:
Zend_Controller_Front::run('/path/to/controllers');
/* -- создание маршрутизатора -- */
$router = new Zend_Controller_RewriteRouter();
$router->addRoute('user',
'user/:username',
array('controller' => 'user', 'action' => 'info')
);
/* -- установка его во фронт-контроллере -- */
$ctrl = Zend_Controller_Front::getInstance();
$ctrl->setRouter($router);
/* -- установка директории контроллеров и запуск диспетчеризации -- */
$ctrl->setControllerDirectory('/path/to/controllers');
$ctrl->dispatch();
Рекомендуется использовать объект ответа для сбора содержимого и
заголовков. Это дает большую гибкость при переключении
между разными форматами вывода (например, JSON или XML вместо XHTML)
в приложениях. По умолчанию dispatch() будет возвращать
ответ, отправляя заголовки и выводя весь контент. Можно также
сделать так, чтобы фронт-контроллер возвращал ответ, используя метод
returnResponse(), и затем выводить ответ так, как нужно
вам. Будущая версия фронт-контроллер может принуждать к
использованию объекта ответа посредством буферизации вывода.
Также добавлено много новых функциональных возможностей, расширяющих существующий API, они описаны в документации.
Основные изменения, о которых следует знать, касаются расширения существующих компонент. Наиболее важные из них следующие:
-
Zend_Controller_Front::dispatch()по умолчанию отлавливает все исключения в объекте ответа и не отображает их для предотвращения раскрытия данных о системе. Вы можете переопределить это поведение несколькими способами:-
Установка
throwExceptions()во фронт-контроллере:$front->throwExceptions(true); -
Установка
renderExceptions()в объекте ответа:$response->renderExceptions(true); $front->setResponse($response); $front->dispatch(); // или: $front->returnResponse(true); $response = $front->dispatch(); $response->renderExceptions(true); echo $response;
-
Zend_Controller_Dispatcher_Interface::dispatch()теперь принимает и возвращает объект запроса Объект запроса вместо меткиZend_Controller_Dispatcher_Token.Zend_Controller_Router_Interface::route()теперь принимает и возвращает объект ответа Объект запроса вместо меткиZend_Controller_Dispatcher_Token-
Изменения
Zend_Controller_Actionвключают в себя следующие:Его конструктор теперь включает в себя три аргумента:
Zend_Controller_Request_Abstract $request,Zend_Controller_Response_Abstract $responseиarray $params(необязательный).Zend_Controller_Action::__construct()использует их для установки запроса, ответа и свойств объекта (аргументов вызова); переопределяя конструктор, вам следует реализовать те же операции. Но лучше использовать методinit()для выполнения любого конфигурирования экземпляра класса, так как этот метод вызывается в конце конструктора.Метод
run()теперь не определен с ключевым словомfinal, но он также и не используется во фронт-контроллере; единственным его назначением является использование класса как контроллера страниц. Теперь он принимает два необязательных аргумента –Zend_Controller_Request_Abstract $requestиZend_Controller_Response_Abstract $response.indexAction()уже не обязателен для определения, но все же рекомендуется определять его в качестве действия по умолчанию. Это позволяет использовать RewriteRouter и контроллеры действий для указания других используемых по умолчанию методов действий.__call()должен переопределяться для автоматической обработки вызовов действий, не определенных в классе контроллера.Метод
_redirect()теперь принимает второй необязательный аргумент, HTTP-код, который должен возвращаться при перенаправлении, и третий необязательный аргумент,$prependBase, который указывает, что базовый URL, зарегистрированный в объекте запроса, должен предшествовать URL, переданному в первом аргументе.-
Свойство
_actionбольще не устанавливается. Это свойство было объектом классаZend_Controller_Dispatcher_Token, которй больше не существует в текущем воплощении. Единственным назначением метки (token) было предоставление информации о запрошенных контроллере, действии и параметрах URL. Эта информация теперь доступна в объекте запроса, и доступ к ней можно получить следующим образом:// Извлечение имени запрошенного контроллера // Ранее доступ был через $this->_action->getControllerName(). // Пример ниже использует getRequest(), хотя вы можете обращаться напрямую // ко свойству $_request; рекомендуется использовать getRequest(), поскольку // родительский класс может переопределить доступ к объекту запроса. $controller = $this->getRequest()->getControllerName(); // Извлечение имени запрошенного действия // Ранее доступ был через $this->_action->getActionName(). $action = $this->getRequest()->getActionName(); // Извлечение параметров запроса // Оно не изменилось; _getParams() и _getParam() просто вызывают аналогичные // методы объекта запроса $params = $this->_getParams(); // запрашивается параметр 'foo', если параметр не найден, // то используется значение по умолчанию 'default' $foo = $this->_getParam('foo', 'default'); -
Удален метод
noRouteAction(). Подходящим способом обработки несуществующих методов действий будет перенаправление к действию по умолчанию через__call():public function __call($method, $args) { // Если запрошен несуществующий метод действия, то вызывается метод // действия по умолчанию: if ('Action' == substr($method, -6)) { return $this->defaultAction(); } throw new Zend_Controller_Exception('Invalid method called'); }
Удален метод
Zend_Controller_RewriteRouter::setRewriteBase(). Вместо него используйтеZend_Controller_Front::setBaseUrl()(илиZend_Controller_Request_Http::setBaseUrl(), если используется класс запроса).Zend_Controller_Plugin_Interfaceбыл заменен наZend_Controller_Plugin_Abstract. Все методы теперь принимают и возвращают объект ответа Объект запроса вместо метки диспетчеризации.
| Исключения |
Select a Version
Languages Available
Components
Search the Manual
Navigation
- Руководство разработчика
- Руководство разработчика
- Zend_Controller
- Zend_Controller - Быстрый старт
- Основы Zend_Controller
- Фронт-контроллер
- Объект запроса
- Стандартный маршрутизатор: Zend_Controller_Router_Rewrite
- Диспетчер
- Контроллеры действий
- Помощники действий
- Объект ответа
- Плагины
- Использование определенной соглашением модульной структуры директорий
- Исключения
- Переход с предыдущих версий
