Zend Framework предоставляет некоторые альтернативы принятым по умолчанию классам, в которые входят объекты запросов, маршрутизаторы и объекты ответов.
Zend_Controller_Request_Http
предоставляет
объект запроса для использования в среде HTTP.
Zend_Controller_Request_Http
является классом
запроса, используемым Zend_Controller_Dispatcher
по умолчанию.
Zend_Controller_Request_Http
инкапсулирует доступ
к релевантным значениям, таким, как ключевое имя и значение
для переменных маршрутизатора и все дополнительные параметры,
полученные из URI. Посредством передачи к
Zend_Controller_Request_Http
он также предоставяет
доступ к значениям, содержащимся в суперглобальных переменных
как к открытым членам и управляет текущим базовым URL и URI
запроса. Суперглобальные значения не могут быть установлены в
объекте запроса, за исключением методов setParam/getParam
для установки или извлечения пользовательских переменных.
![]() |
Суперглобальные данные |
---|---|
Когда обращаетесь к суперглобальным переменным через
|
К определенным суперглобальным массивам можно также обращаться
через открытые методы. Например, можно получить необработанное
значение $_POST['user']
посредством вызова метода
getPost('user')
в объекте запроса.
Zend_Controller_Request_Http
позволяет использовать
Zend_Controller_RewriteRouter в поддиректориях.
Zend_Controller_Request_Http будет пытаться автоматически
определить ваш базовый URL и установить его.
Например, если вы храните файл загрузки index.php
в
поддиректории веб-сервера, которая называется
/projects/myapp/index.php
, то базовый URL
(базовый адрес перезаписи) должен быть установлен в
/projects/myapp
. Эта стока будет исключаться из
начала пути перед любыми вычислениями соответствий маршрутов.
Это освобождает от необходимости ее указывания в начале каждого
маршрута. Маршрут 'user/:username'
будет
соответствовать URI вида
http://localhost/projects/myapp/user/martel
и
http://example.com/user/martel
.
![]() |
Определение URL чувствительно к регистру |
---|---|
Автоматическое определение базового URL является
чувствительно к регистру, поэтому убедитесь, что ваш URL
соответствует имени поддиректории в файловой системе (даже
на платформе Windows). Если не соответствует, то будет
вызываться действие |
Если базовый URL определяется некорректно, вы можете заменить
его своим базовым путем с помощью метода
setBaseUrl()
, который есть в классах
Zend_Http_Request
,
Zend_Controller_Request_Http
и
Zend_Controller_Front
. Легче всего установить его
через Zend_Controller_Front
, который передаст его
объекту запроса. Пример установки своего базового URL:
$router = new Zend_Controller_RewriteRouter(); $controller = Zend_Controller_Front::getInstance(); $controller->setControllerDirectory('./application/controllers') ->setRouter($router) ->setBaseUrl('/projects/myapp'); // set the base url! $response = $controller->dispatch();
Zend_Controller_RewriteRouter
является новой
версией маршрутизатора фреймворка. Маршрутизация является
процессом принятия конечной точки URI (той части URI, которая
идет после базового URL) и ее разложения на параметры
для определения того, какой контроллер и какое действие этого
контроллера должны получить запрос. Значения контроллера,
действия и необязательных параметров упаковывается в объект
Zend_Controller_Request_Http
, который затем
обрабатывается Zend_Controller_Dispatcher
.
Маршрутизация производится только один раз – когда вначале
получен запрос и до того, как первый контроллер будет запущен.
Zend_Controller_RewriteRouter
предназначен для
того, чтобы обеспечить функциональность, подобную mod_rewrite,
с применением чистого php. Он отчасти основан на маршрутизации
в Ruby on Rails и не требует каких-либо предварительных знаний
о перезаписи URL веб-сервером. Он спроектирован для работы с
единственным правилом mod_rewrite, пример которого приведен
ниже:
RewriteEngine on RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
или:
RewriteEngine on RewriteCond %{SCRIPT_FILENAME} !-f RewriteCond %{SCRIPT_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1
RewriteRouter может также использоваться с веб-сервером IIS, если Isapi_Rewrite был установлен как расширение Isapi со следующими правилами перезаписи:
RewriteRule ^[\w/\%]*(?:\.(?!(?:js|ico|gif|jpg|png|css)$)[\w\%]*$)? /index.php [I]
![]() |
IIS Isapi_Rewrite |
---|---|
Если используется IIS, то
|
Если используется Lighttpd, то валидным будет следующее правило перезаписи:
url.rewrite-once = ( ".*\.(js|ico|gif|jpg|png|css)$" => "$0", "" => "/index.php")
Чтобы использовать RewriteRouter, нужно инстанцировать его, добавить маршруты и установить его в контроллере. Следующий код иллюстрирует эту процедуру:
/* Создание маршрутизатора */ $router = new Zend_Controller_RewriteRouter(); $router->addRoute( 'user', new Zend_Controller_Router_Route('user/:username', array('controller' => 'user', 'action' => 'info')) ); /* Установка его в контроллере */ $ctrl = Zend_Controller_Front::getInstance(); $ctrl->setRouter($router);
Сущностью RewriteRouter является определение пользовательских
маршрутов. Маршруты создаются вызовом метода
addRoute()
и передачей ему нового
экземпляра Zend_Controller_Router_Route
:
$router->addRoute('user', new Zend_Controller_Router_Route('user/:username'));
Первым параметром является имя маршрута. Сейчас он
является избыточным, но в будущем будет использоваться в
вспомогательном классе вида (view) для легкой генерации URL
в ваших видах. Если нужно воспользоваться ранее
сконфигурированным маршрутом, то можно получить его
с помощью метода getRoute
. Вторым параметром
является экземпляр Zend_Controller_Router_Route
.
Первым параметром для конструктора
Zend_Controller_Router_Route
является маршрут,
который будет сопоставляться с URL – например, маршрут в примере
выше будет соответствовать
http://example.com/user/martel
. Двоеточие в
маршруте обозначает переменную URL. После успешной
маршрутизации значения всех определенных переменных будут
добавлены в Zend_Controller_Request. К ним можно будет получить
доступ через методы Zend_Controller_Request::getParam или
Zend_Controller_Action::_getParam. В нашем примере параметру под
именем username будет присвоено значение 'martel'.
![]() |
Порядок сопоставления |
---|---|
Маршруты сопоставляются в обратном порядке, поэтому удостоверьтесь, что наиболее общие маршруты определены первыми. |
![]() |
Использование символов |
---|---|
Текущая реализация позволяет использовать любые символы, кроме прямой косой черты (/), в идентификаторе переменной, но сильно рекомендуется использовать в них только символы, допустимые для переменных в php. Есть вероятность, что в будущем реализация изменится, и это может вызвать ошибки в вашем коде. |
Есть две специальные переменные, которые можно использовать в
маршрутах — ':controller' и ':action'. Эти специальные
переменные могут использоваться для получения контроллера и/или
действия, выбранных в URL. Переменная ':action' всегда должна
быть определена в маршруте или как параметр по умолчанию.
Переменная 'controller' по умолчанию будет
IndexController
, если не была определена.
![]() |
Специальные переменные |
---|---|
Имена специальных переменных могут отличаться, если вы
измените значения по умолчанию в
|
$router->addRoute( 'user', new Zend_Controller_Router_Route(':controller/:action') );
Если вы наберете в вашем броузере адрес
'http://example.com/news/latest', то при сопоставлении с таким
маршрутом Zend_Controller_Dispatcher
вызовет метод
latestAction в вашем классе контроллера NewsController.
Любая переменная в маршруте может иметь значение по умолчанию.
Для его определения вы должны добавить второй параметр для
конструктора Zend_Controller_Router_Route
. Этот
параметр является массивом с ключами, соответствующими именам
переменных, и значениями, соответствующими желаемым значениям
этих переменных по умолчанию.
$router->addRoute( 'archive', new Zend_Controller_Router_Route('archive/:year', array('year' => 2006)) );
Этот маршрут будет соответствовать таким URL, как 'http://example.com/archive/2005' и 'http://example.com/archive'. В последнем случае переменная ':year' будет иметь значение 2006.
В примере выше результатом будет только добавление переменной ':year' в запрос. Маршрутизация не будет выполняться корректно до тех пор, пока не будут установлены параметры контроллера и действия. Для того, чтобы сделать этот код более полезным, вы должны указать конкретные контроллер и действие как значения по умолчанию.
$router->addRoute( 'archive', new Zend_Controller_Router_Route('archive/:year', array('year' => 2006, 'controller' => 'archive', 'action' => 'show') );
Результатом будет вызов действия showAction в классе контроллера ArchiveController.
Можно добавить третий параметр в вызове конструктора
Zend_Controller_Router_Route
, в котором
устанавливаются требования к переменным. Они указываются в виде
регулярных выражений.
$router->addRoute( 'archive', new Zend_Controller_Router_Route('archive/:year', array('year' => 2006), array('year' => '\d+')) );
![]() |
Особенности маршрутизации |
---|---|
В отличие от Ruby on Rails, ZF RewriteRouter будет
использовать значение по умолчанию, если нет соответствия
требованиям, определенным в третьем параметре. Таким
образом, в случае URL
|
В отличие от основного маршрутизатора Router, RewriteRouter может использоваться в поддиректориях. Существовавший ранее метод setRewriteBase() теперь не доступен. Вместо этого базовый URL автоматически определяется в Zend_Controller_Request_Http.
Если базовый URL определяется некорректно, то вы можете переопределить его через метод setBaseUrl() объекта Zend_Controller_Request_Http (см. Раздел 5.4.2.3, «Базовый URL и поддиректории»).
Zend_Controller_RewriteRouter
изначально
сконфигурирован с одним маршрутом по умолчанию для обеспечения
совместимости с первой версией маршрутизатора. Он будет
соответствовать URI вида 'controller/action'
и по
умолчанию будет также соответствовать любым дополнительным
параметрам, добавленным в конец URI. Он сконфигурирован как:
// Маршрут для совместимости с первой версией маршрутизатора $compat = new Zend_Controller_Router_Route(':controller/:action/*', array('controller' => 'index', 'action' => 'index')); $this->addRoute('default', $compat);
![]() |
Сопоставление URI |
---|---|
Zend_Controller_RewriteRouter сконфигурирован для обратной
совместимости. Он будет автоматически использовать маршрут
|
Если вы не хотите использовать маршрут по умолчанию, то можете
удалить его, используя метод removeDefaultRoutes()
:
// Удаление маршрута по умолчанию $router->removeDefaultRoutes();
В примерах выше все импользуемые маршруты были динамическими – маршруты, которые содержат паттерны для сопоставления с URI. Тем не менее, определенные маршруты могут быть неизменными, и применение к ним методов регулярных выражений будет совершенно излишним. Решением данной ситуации будет использование статических маршрутов:
$loginRoute = new Zend_Controller_Router_StaticRoute('login', array('controller' => 'login', 'action' => 'form')); $router->addRoute('login', $static);
Иногда было бы более удобным обновлять конфигурационные данные
для новых маршрутов, чем изменять код. Это возможно через метод
addConfig()
. По существу, вы создаете конфигурацию,
совместимую с Zend_Config, считываете ее в своем коде и
передаете RewriteRouter.
/** * Пример INI: * routes.archive.route = "archive/:year/*" * routes.archive.defaults.controller = archive * routes.archive.defaults.action = show * routes.archive.defaults.year = 2000 * routes.archive.reqs.year = "\d+" * * routes.news.type = "Zend_Controller_Router_StaticRoute" * routes.news.route = "news" * routes.news.defaults.controller = "news" * routes.news.defaults.action = "list" */ $config = new Zend_Config_Ini($file); $router = new Zend_Controller_RewriteRouter(); $router->addConfig($config, 'routes');
В примере выше мы говорим маршрутизатору, чтобы он использовал
раздел 'routes' в файле INI для определения своих маршрутов.
Ключ первого уровня в этом разделе используется для имени
маршрута, в примере выше определяются маршруты 'archive' и
'news'. Каждый маршрут требует, как минимум, запись 'route',
одну или более записей 'defaults', необязательно может быть одна
или более записей 'reqs' (сокращение от 'required'). Все это
соответствет трем аргументам, предоставляемым объекту
Zend_Controller_Router_Route_Interface
.
Опция 'type' может использоваться для определения класса,
используемого для данного маршрута, по умолчанию используется
класс Zend_Controller_Router_Route
. В примере выше
для маршрута 'news' должен использоваться класс
Zend_Controller_Router_StaticRoute
.
Zend_Controller_Response_Http
является объектом ответа,
пригодным к использованию в среде HTTP. Он содержит методы для
установки, получения и удаления заголовков, а также метод
__toString()
, который отправляет все заголовки
одновременно до того, как будет возвращено содержимое ответа.
setHeader()
принимает два аргумента – тип заголовка и
значение заголовка. Если передан третий необязательный параметр и он
имеет значение true
, то производится принудительная
замена значения заголовка с тем же типом, если он уже был
зарегистрирован.