<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.controller.migration">
    <title>Переход с предыдущих версий</title>

    <para>
        API компонент системы MVC претерпевал изменения со временем. Если вы
        начали использование Zend Framework с его ранних версий, то следуйте
        приведенным ниже рекомендациям по переносу вашего кода на новую
        архитектуру.
    </para>

    <sect2 id="zend.controller.migration.fromoneseventooneeight">
        <title>Переход с 1.7.x на 1.8.0 и более поздние версии</title>

        <sect3 id="zend.controller.migration.fromoneseventooneeight.router">
            <title>Изменения в стандартном маршруте</title>

            <para>
                Поскольку в новый стандартный маршрут были добавлены
                переводимые сегменты, символ <code>@</code> стал
                специальным символом в начале сегмента маршрута.
                Для того, чтобы можно было использовать его в статических
                сегментах, вы должны экранировать его путем добавления второго
                символа <code>@</code>. То же самое правило теперь применяется
                и к символу <code>:</code>.
            </para>
        </sect3>
    </sect2>

    <sect2 id="zend.controller.migration.fromonesixtooneseven">
        <title>Переход с 1.6.x на 1.7.0 и более поздние версии</title>

        <sect3 id="zend.controller.migration.fromonesixtooneseven.dispatcher">
            <title>Изменения в интерфейсе диспетчера</title>

            <para>
                Пользователи обратили наше внимание на тот факт, что
                <classname>Zend_Controller_Action_Helper_ViewRenderer</classname>
                использует не присутствующий в интерфейсе метод из
                абстрактного класса диспетчера. Мы добавили
                этот метод в интерфейс диспетчера для того,
                чтобы гарантировать работу созданного вами диспетчера с
                классами, входящими в поставку Zend Framework:
            </para>

            <itemizedlist>
                <listitem><para>
                    <code>formatModuleName()</code>: должен принимать
                    необработанное имя контроллера (в том виде, в котором оно
                    хранится в объекте запроса) и преобразовывать его в имя
                    класса контроллера, наследующего от
                    <classname>Zend_Controller_Action</classname>.
                </para></listitem>
            </itemizedlist>
        </sect3>
    </sect2>

    <sect2 id="zend.controller.migration.fromoneohtoonesix">
        <title>Переход с 1.5.x на 1.6.0 и более поздние версии</title>

        <sect3 id="zend.controller.migration.fromoneohtoonesix.dispatcher">
            <title>Изменения в интерфейсе диспетчера</title>

            <para>
                Пользователи обратили наше внимание на тот факт, что
                <classname>Zend_Controller_Front</classname> и
                <classname>Zend_Controller_Router_Route_Module</classname> используют
                методы диспетчера, которые не определены в его интерфейсе.
                Мы добавили следующие три метода в его интерфейс для того,
                чтобы гарантировать работу созданного вами диспетчера с
                классами, входящими в поставку Zend Framework:
            </para>

            <itemizedlist>
                <listitem><para>
                    <code>getDefaultModule()</code>: должен возвращать имя
                    используемого по умолчанию модуля.
                </para></listitem>

                <listitem><para>
                    <code>getDefaultControllerName()</code>: должен возвращать
                    имя используемого по умолчанию контроллера.
                </para></listitem>

                <listitem><para>
                    <code>getDefaultAction()</code>: должен возвращать имя
                    используемого по умолчанию действия.
                </para></listitem>
            </itemizedlist>
        </sect3>
    </sect2>

    <sect2 id="zend.controller.migration.fromoneohtoonefive">
        <title>Переход с 1.0.x на 1.5.0 и более поздние версии</title>

        <para>
            Хотя основной набор функциональных возможностей остался тем же, и
            все документированные возможности не претерпели изменений, есть одна
            <emphasis>недокументированная</emphasis> "возможность", которая была
            изменена.
        </para>

        <para>
            При написании URL-ов, документированным способом написания имен
            действий в формате camelCase является использование разделителей
            слов. По умолчанию это '.' или '-', но они могут быть заменены на
            другие символы путем настройки диспетчера. Диспетчер внутри себя
            приводит имена действий к нижнему регистру и использует эти
            разделители слов для "пересборки" имен действий с использованием
            формата camelCase. Но из-за того, что функции PHP не чувствительны к
            регистру, вы <emphasis>могли</emphasis> по-прежнему писать URL-ы в
            формате camelCasе, и результатом был запуск тех же методов
            действий. Например, 'camel-cased' должен был преобразовываться
            диспетчером в 'camelCasedAction', а 'camelCased' - в
            'camelcasedAction', но из-за нечувствительности PHP к регистру имен
            функций в обоих случаях будет произведен вызов одного и того же
            метода.
        </para>

        <para>
            Это вызывало проблемы с ViewRenderer при определении имени скрипта
            вида. Документированный способ состоит в том, что все разделители
            слов преобразуются в тире, и слова приводятся к нижнему регистру.
            Это создает семантическую связь между действиями и скриптами видов,
            а нормализация гарантирует, что скрипты могут быть найдены. Тем не
            менее, если вызывается действие с именем 'camelCased' и благополучно
            обработано, то разделитель слов более не присутствует в имени, и
            ViewRenderer пытается вызвать другой скрипт вида -
            'camelcased.phtml' вместо 'camel-cased.phtml'.
        </para>

        <para>
            Некоторые разработчики полагались на эту незапланированную
            "возможность". Тем не менее, некоторые изменения в дереве 1.5.0,
            привели к тому, что ViewRenderer более не ищет такие пути;
            семантическая связь теперь усилена. Главное, диспетчер
            теперь чувствителен к регистру в именах действий. Это значит, что
            ссылка на действие через URL с использованием формата camelCase
            не будет приводить к вызову того же метода, что и с использованием
            разделителей слов (т.е. 'camel-casing').
        </para>

        <para>
            Если получилось, что вы используете эту "возможность", то в имеете
            несколько вариантов решения:
        </para>

        <itemizedlist>
            <listitem><para>
                    Наилучший вариант: переименуйте ваши скрипты вида. Плюсы:
                    будущая совместимость. Минусы: если вы имеете много скриптов
                    вида, которые полагаются на старое, незапланированное
                    поведение, то вам придется сделать много переименований.
            </para></listitem>

            <listitem>
                <para>
                    Второй лучший вариант: ViewRenderer теперь делегирует
                    определение скриптов вида инфлектору
                    <classname>Zend_Filter_Inflector</classname>; вы можете изменить
                    правила инфлектора так, чтобы он более не разделял слова в
                    имени действия знаком тире:
                </para>

                <programlisting language="php"><![CDATA[
$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'
));
]]></programlisting>

                <para>
                    Приведенный выше код изменит инфлектор таким образом, чтобы
                    он более не разделял слова в имени действия знаком тире; вы
                    можете также убрать фильтр 'StringToLower', если хотите,
                    чтобы реальные имена скриптов вида тоже были в формате
                    camelCase.
                </para>

                <para>
                    Если переименование скриптов вида слишком утомительно или
                    требует много времени, то этот вариант будет наилучшим
                    решением на тот период, пока вы не найдете время на
                    переименование.
                </para>
            </listitem>

            <listitem>
                <para>
                    Менее желательное решение: Вы можете заставить диспетчер
                    принимать имена действий в формате camelCase, установив
                    новый флаг фронт-контроллера 'useCaseSensitiveActions':
                </para>

                <programlisting language="php"><![CDATA[
$front->setParam('useCaseSensitiveActions', true);
]]></programlisting>

                <para>
                    Это позволит вам использовать camelCase в URL-ах и они будут
                    приводить к запуску тех действий, что и при использовании
                    разделителей слов. Тем не менее, это будет означать, что
                    исходная проблема может повлечь за собой другие; возможно,
                    вам потребуется также использовать описанный выше второй
                    вариант, чтобы все работало наверняка.
                </para>

                <para>
                    Также заметьте, что использование этого флага приведет к
                    появлению предупреждения (notice) о том, что его
                    использование не рекомендуется.
                </para>
            </listitem>
        </itemizedlist>
    </sect2>

    <sect2 id="zend.controller.migration.fromzeroninethree">
        <title>Переход с 0.9.3 на 1.0.0RC1 и более поздние версии</title>

        <para>
            Основные изменения, появившиеся в 1.0.0RC1 - это добавление
            включенного по умолчанию плагина
            <link linkend="zend.controller.plugins.standard.errorhandler">ErrorHandler</link>
            и помощника действий <link linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>.
            Пожалуйста, прочитайте внимательно документацию к ним, чтобы понять,
            как они работают, и как они могут повлиять на работу ваших
            приложений.
        </para>

        <para>
            Плагин <code>ErrorHandler</code> производит в методе
            <code>postDispatch()</code> проверку на предмет исключений и
            переход (forwarding) к определенному контроллеру-обработчику
            исключений. Вы можете отключить его путем установки параметра
            <code>noErrorHandler</code> во фронт-контроллере:
        </para>

        <programlisting language="php"><![CDATA[
$front->setParam('noErrorHandler', true);
]]></programlisting>

        <para>
            Помощник действий <code>ViewRenderer</code> автоматизирует
            добавление вида в контроллеры действий и производит авторендеринг
            скрипта вида, выбранного по текущему действию. Первая проблема, с
            которой вы можете встретиться - у вас есть действия,
            которые не производят рендеринг скриптов вида и не производят
            переход или перенаправление, поскольку <code>ViewRenderer</code>
            будет пытаться запустить скрипт вида, выбранного по имени действия.
        </para>

        <para>
            Есть несколько стратегий, используя которые, вы можете обновить свой
            код. В краткострочной перспективе решением может быть глобальное
            отключение <code>ViewRenderer</code> во фронт-контроллере до
            начала процесса диспетчеризации:
        </para>

        <programlisting language="php"><![CDATA[
// $front является экземпляром Zend_Controller_Front
$front->setParam('noViewRenderer', true);
]]></programlisting>

        <para>
            Но в долгосрочной перспективе это не лучшее решение, поскольку
            оно означает, что вам в будущем придется писать больше кода.
        </para>

        <para>
            Когда вы будете готовы начать использование функционала
            <code>ViewRenderer</code>, то необходимо проверить некоторые места в
            коде контроллеров. Первое, просмотрите методы действий (методы,
            заканчивающиеся на 'Action') и определите, что делает каждый метод.
            Если не происходит ничего из следующего, то нужно произвести
            изменения:
        </para>

        <itemizedlist>
            <listitem><para>
                Вызов <varname>$this-&gt;render()</varname>
            </para></listitem>
            <listitem><para>
                Вызов <varname>$this-&gt;_forward()</varname>
            </para></listitem>
            <listitem><para>
                Вызов <varname>$this-&gt;_redirect()</varname>
            </para></listitem>
            <listitem><para>
                Вызов помощника действий <code>Redirector</code>
            </para></listitem>
        </itemizedlist>

        <para>
            Наиболее легким способом будет отключение авторендеринга в данном
            методе:
        </para>

        <programlisting language="php"><![CDATA[
$this->_helper->viewRenderer->setNoRender();
]]></programlisting>

        <para>
            Если вы обнаружили, что ни один из методов действий не производит
            рендеринг, переход или перенаправление, то, скорее всего, нужно
            поместить эту строку в методы
            <code>preDispatch()</code> или <code>init()</code>:
        </para>

        <programlisting language="php"><![CDATA[
public function preDispatch()
{
    // отключение авторендеринга скриптов вида
    $this->_helper->viewRenderer->setNoRender()
    // ... еще код ..
}
]]></programlisting>

        <para>
            Если вы вызываете <code>render()</code> и используете
            <link linkend="zend.controller.modular">определенную соглашением
            модульную структуру директорий</link>, то нужно
            изменить свой код так, чтобы использовался авторендеринг:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    Если производится рендеринг нескольких скриптов вида в
                    одном действии, то не нужно ничего изменять.
                </para>
            </listitem>
            <listitem>
                <para>
                    Если производится простой вызов метода
                    <code>render()</code> без аргументов, то можете удалить
                    соответствующие строки.
                </para>
            </listitem>
            <listitem>
                <para>
                    Если вызывается <code>render()</code> с аргументами и не
                    производится впоследствии каких-либо действий или рендеринга
                    нескольких скриптов вида, то можно заменить эти вызовы на
                    чтение <varname>$this-&gt;_helper-&gt;viewRenderer()</varname>.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            На тот случай, если вы не используете определенную соглашением
            модульную структуру директорий, есть набор методов для
            установки базового пути к видам и спецификаций пути ко скрипту,
            поэтому вы сможете и в этом случае использовать
            <code>ViewRenderer</code>. Информацию об этих методах вы найдете в
            <link linkend="zend.controller.actionhelpers.viewrenderer">документации
            по ViewRenderer</link>
        </para>

        <para>
            Если вы используете объект вида из реестра, создали свой объект
            вида, либо используете другие реализации встроенного, то может
            потребоваться добавить этот объект в <code>ViewRenderer</code>. Это
            легко можно сделать в любой момент времени.
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    До начала диспетчеризации экземпляра фронт-контроллера:
                </para>

                <programlisting language="php"><![CDATA[
// Предполагается, что $view уже определен
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
]]></programlisting>
            </listitem>

            <listitem>
                <para>
                    В любой точке процесса загрузки (bootstrap process):
                </para>

                <programlisting language="php"><![CDATA[
$viewRenderer =
    Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->setView($view);
]]></programlisting>
            </listitem>
        </itemizedlist>

        <para>
            Есть много способов модификации <code>ViewRenderer</code>, включая
            установку других скриптов вида для рендеринга, определение замещений
            для всех замещаемых элементов пути ко скрипту вида (включая
            суффикс), выбор именованного сегмента ответа в качестве
            используемого и др. Если вы не используете определенную соглашением
            модульную структуру директорий, то можете ассоциировать с
            <code>ViewRenderer</code> другие спецификации путей.
        </para>

        <para>
            Рекомендуется адаптировать свой код для использования
            <code>ErrorHandler</code> и <code>ViewRenderer</code>, так как
            сейчас это лежащий в основе фреймворка функционал.
        </para>
    </sect2>

    <sect2 id="zend.controller.migration.fromzeroninetwo">
        <title>Переход с 0.9.2 на 0.9.3 и более поздние версии</title>

        <para>
            В версии 0.9.3 были добавлены <link
            linkend="zend.controller.actionhelpers">помощники действий</link>
            (action helpers).
            Это изменение включает в себя удаление перечисленных ниже методов
            из-за того, что сейчас они инкапсулированы в
            <link linkend="zend.controller.actionhelpers.redirector">помощнике
            перенаправлений</link> (redirector action helper):
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <code>setRedirectCode()</code>; используйте
                    <code>Zend_Controller_Action_Helper_Redirector::setCode()</code>.
                </para>
            </listitem>
            <listitem>
                <para>
                    <code>setRedirectPrependBase()</code>; используйте
                    <code>Zend_Controller_Action_Helper_Redirector::setPrependBase()</code>.
                </para>
            </listitem>
            <listitem>
                <para>
                    <code>setRedirectExit()</code>; используйте
                    <code>Zend_Controller_Action_Helper_Redirector::setExit()</code>.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            Более подробную информацию о том, как извлекать и работать с
            объектами действий, читайте в <link
            linkend="zend.controller.actionhelpers">документации по помощникам
            действий</link>. Об установке опций перенаправления и альтернативных
            методах перенаправления читайте в <link
            linkend="zend.controller.actionhelpers.redirector">документации по
            помощнику перенаправлений</link>.
        </para>
    </sect2>

    <sect2 id="zend.controller.migration.fromzerosix">
        <title>Переход с 0.6.0 на 0.8.0 и более поздние версии</title>

        <para>
            Базовое использование компонент MVC не изменилось:
        </para>

        <programlisting language="php"><![CDATA[
Zend_Controller_Front::run('/path/to/controllers');
]]></programlisting>

        <para>
            Тем не менее, структура директорий была подвергнута пересмотру,
            некоторые компоненты были удалены, другие добавлены или
            переименованы. Изменения включают в себя следующее:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <classname>Zend_Controller_Router</classname> удален в пользу
                    использования Rewrite Router.
                </para>
            </listitem>

            <listitem>
                <para>
                    <classname>Zend_Controller_RewriteRouter</classname> переименован в
                    <classname>Zend_Controller_Router_Rewrite</classname>, теперь это
                    стандартный маршрутизатор, поставляемый с фреймворком.
                    <classname>Zend_Controller_Front</classname> будет использовать его по
                    умолчанию, если не был установлен другой маршрутизатор.
                </para>
            </listitem>

            <listitem>
                <para>
                    Добавлен новый класс маршрута для использования с Rewrite
                    Router - <classname>Zend_Controller_Router_Route_Module</classname>.
                    Он включает в себя маршрут по умолчанию, используемый
                    MVC, и поддерживает <link
                        linkend="zend.controller.modular">модули
                        контроллеров</link>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <classname>Zend_Controller_Router_StaticRoute</classname> переименован
                    в <classname>Zend_Controller_Router_Route_Static</classname>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <classname>Zend_Controller_Dispatcher</classname> переименован в
                    <classname>Zend_Controller_Dispatcher_Standard</classname>.
                </para>
            </listitem>

            <listitem>
                <para>
                    Аргументы метода
                    <code>Zend_Controller_Action::_forward()</code> изменились.
                    Его сигнатура теперь:
                </para>

                <programlisting language="php"><![CDATA[
final protected function _forward($action,
                                  $controller = null,
                                  $module = null,
                                  array $params = null);
]]></programlisting>

                <para>
                    <varname>$action</varname> - обязательный аргумент. Если не был
                    определен контроллер, то предполагается, что вызывается
                    действие в текущем контроллере. <varname>$module</varname> всегда
                    игнорируется, если не определен контроллер. Все переданные в
                    аргументе <varname>$params</varname> параметры будут добавлены в
                    объект запроса. Если вы не запрашиваете контроллер или
                    модуль, но нужно передать параметры, то просто укажите null
                    на месте соответствующих аргументов.
                </para>
            </listitem>
        </itemizedlist>
    </sect2>

    <sect2 id="zend.controller.migration.fromzerotwo">
        <title>Переход с 0.2.0 и более ранних версий на 0.6.0</title>

        <para>
            Базовое использование компонент системы MVC не изменилось,
            следующий код будет корректно выполняться и в версии 0.6.0:
        </para>

        <programlisting language="php"><![CDATA[
Zend_Controller_Front::run('/path/to/controllers');
]]></programlisting>

        <programlisting language="php"><![CDATA[
/* -- создание маршрутизатора -- */
$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();
]]></programlisting>

        <para>
            Рекомендуется использовать объект ответа для сбора содержимого и
            заголовков. Это дает большую гибкость при переключении
            между разными форматами вывода (например, JSON или XML вместо XHTML)
            в приложениях. По умолчанию <code>dispatch()</code> будет возвращать
            ответ, отправляя заголовки и выводя весь контент. Можно также
            сделать так, чтобы фронт-контроллер возвращал ответ, используя метод
            <code>returnResponse()</code>, и затем выводить ответ так, как нужно
            вам. Будущая версия фронт-контроллер может принуждать к
            использованию объекта ответа посредством буферизации вывода.
        </para>

        <para>
            Также добавлено много новых функциональных возможностей,
            расширяющих существующий API, они описаны в документации.
        </para>

        <para>
            Основные изменения, о которых следует знать, касаются расширения
            существующих компонент. Наиболее важные из них следующие:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <code>Zend_Controller_Front::dispatch()</code> по умолчанию
                    отлавливает все исключения в объекте ответа и не отображает
                    их для предотвращения раскрытия данных о системе. Вы
                    можете переопределить это поведение несколькими способами:
                </para>

                <itemizedlist>
                    <listitem>
                        <para>
                            Установка <code>throwExceptions()</code> во
                            фронт-контроллере:
                        </para>
                        <programlisting language="php"><![CDATA[
$front->throwExceptions(true);
]]></programlisting>
                    </listitem>

                    <listitem>
                        <para>
                            Установка <code>renderExceptions()</code> в объекте
                            ответа:
                        </para>
                        <programlisting language="php"><![CDATA[
$response->renderExceptions(true);
$front->setResponse($response);
$front->dispatch();

// или:
$front->returnResponse(true);
$response = $front->dispatch();
$response->renderExceptions(true);
echo $response;
]]></programlisting>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem><para>
                <code>Zend_Controller_Dispatcher_Interface::dispatch()</code>
                теперь принимает и возвращает объект запроса
                <xref linkend="zend.controller.request" />
                вместо метки <classname>Zend_Controller_Dispatcher_Token</classname>.
            </para></listitem>

            <listitem><para>
                <code>Zend_Controller_Router_Interface::route()</code>
                теперь принимает и возвращает объект ответа
                <xref linkend="zend.controller.request" />
                вместо метки <classname>Zend_Controller_Dispatcher_Token</classname>
            </para></listitem>

            <listitem>
                <para>
                    Изменения <classname>Zend_Controller_Action</classname> включают в
                    себя следующее:
                </para>

                <itemizedlist>
                    <listitem><para>
                        Его конструктор теперь включает в себя три аргумента:
                        <code>Zend_Controller_Request_Abstract $request</code>,
                        <code>Zend_Controller_Response_Abstract $response</code>
                        и <code>array $params</code> (необязательный).
                        <code>Zend_Controller_Action::__construct()</code>
                        использует их для установки запроса, ответа и свойств
                        объекта (аргументов вызова); переопределяя конструктор,
                        вам следует реализовать те же операции.
                        Но лучше использовать метод <code>init()</code> для
                        выполнения любого конфигурирования экземпляра класса,
                        так как этот метод вызывается в конце конструктора.
                    </para></listitem>

                    <listitem><para>
                        Метод <code>run()</code> теперь не определен с ключевым
                        словом <code>final</code>, но он также и не используется
                        во фронт-контроллере; единственным его назначением
                        является использование класса как контроллера страниц.
                        Теперь он принимает два необязательных аргумента –
                        <code>Zend_Controller_Request_Abstract $request</code>
                        и <code>Zend_Controller_Response_Abstract $response</code>.
                    </para></listitem>

                    <listitem><para>
                        <code>indexAction()</code> уже не обязателен для
                        определения, но все же рекомендуется определять его в
                        качестве действия по умолчанию. Это позволяет
                        использовать RewriteRouter и контроллеры действий для
                        указания других используемых по умолчанию методов
                        действий.
                    </para></listitem>

                    <listitem><para>
                        <code>__call()</code> должен переопределяться для
                        автоматической обработки вызовов действий, не
                        определенных в классе контроллера.
                    </para></listitem>

                    <listitem><para>
                        Метод <code>_redirect()</code> теперь принимает второй
                        необязательный аргумент, HTTP-код, который должен
                        возвращаться при перенаправлении, и третий
                        необязательный аргумент, <varname>$prependBase</varname>,
                        который указывает, что базовый URL, зарегистрированный в
                        объекте запроса, должен предшествовать URL, переданному
                        в первом аргументе.
                    </para></listitem>

                    <listitem>
                        <para>
                            Свойство <code>_action</code> больще не
                            устанавливается. Это свойство было объектом класса
                            <classname>Zend_Controller_Dispatcher_Token</classname>,
                            которй больше не существует в текущем воплощении.
                            Единственным назначением метки (token) было
                            предоставление информации о запрошенных контроллере,
                            действии и параметрах URL. Эта информация теперь
                            доступна в объекте запроса, и доступ к ней можно
                            получить следующим образом:
                        </para>

                        <programlisting language="php"><![CDATA[
// Извлечение имени запрошенного контроллера
// Ранее доступ был через $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');
]]></programlisting>
                    </listitem>

                    <listitem>
                        <para>
                            Удален метод <code>noRouteAction()</code>.
                            Подходящим способом обработки несуществующих методов
                            действий будет перенаправление к действию по
                            умолчанию через <code>__call()</code>:
                        </para>

                        <programlisting language="php"><![CDATA[
public function __call($method, $args)
{
    // Если запрошен несуществующий метод действия, то вызывается метод
    // действия по умолчанию:
    if ('Action' == substr($method, -6)) {
        return $this->defaultAction();
    }

    throw new Zend_Controller_Exception('Invalid method called');
}
]]></programlisting>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem><para>
                Удален метод
                <code>Zend_Controller_RewriteRouter::setRewriteBase()</code>.
                Вместо него используйте
                <code>Zend_Controller_Front::setBaseUrl()</code> (или
                <code>Zend_Controller_Request_Http::setBaseUrl()</code>,
                если используется класс запроса).
            </para></listitem>

            <listitem><para>
                <classname>Zend_Controller_Plugin_Interface</classname> был заменен на
                <classname>Zend_Controller_Plugin_Abstract</classname>. Все методы теперь
                принимают и возвращают объект ответа
                <xref linkend="zend.controller.request" /> вместо метки
                диспетчеризации.
            </para></listitem>
        </itemizedlist>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
