mirror of
https://github.com/yiisoft/yii.git
synced 2026-03-21 15:36:53 +01:00
226 lines
14 KiB
Plaintext
226 lines
14 KiB
Plaintext
Контроллер
|
||
==========
|
||
`Контроллер (controller)` — это экземпляр класса [CController] или производного от него.
|
||
Контроллер создается приложением в случае, когда пользователь его запрашивает.
|
||
При запуске контроллер выполняет соответствующее действие, что обычно
|
||
подразумевает создание соответствующих моделей и рендеринг необходимых представлений.
|
||
В самом простом случае `действие` — это метод класса контроллера, название
|
||
которого начинается на `action`.
|
||
|
||
У контроллера есть действие по умолчанию, которое выполняется
|
||
в случае, когда пользователь не указывает действие при запросе.
|
||
По умолчанию это действие называется `index`. Изменить его можно путем установки
|
||
значения [CController::defaultAction].
|
||
|
||
Ниже приведен минимальный код класса контроллера. Поскольку этот контроллер не
|
||
определяет ни одного действия, обращение к нему приведет к вызову исключения.
|
||
|
||
~~~
|
||
[php]
|
||
class SiteController extends CController
|
||
{
|
||
}
|
||
~~~
|
||
|
||
|
||
Маршрут
|
||
-------
|
||
Контроллеры и действия опознаются по их идентификаторам.
|
||
Идентификатор контроллера — это запись формата `path/to/xyz`, соответствующая
|
||
файлу класса контроллера `protected/controllers/path/to/XyzController.php`, где `xyz`
|
||
следует заменить реальным названием класса (например, `post` соответствует
|
||
`protected/controllers/PostController.php`). Идентификатор действия — это название
|
||
метода без префикса `action`. Например, если класс контроллера содержит метод
|
||
`actionEdit`, то идентификатор соответствующего действия — `edit`.
|
||
|
||
> Note|Примечание: До версии 1.0.3 идентификатор контроллера указывался как
|
||
`path.to.xyz` вместо `path/to/xyz`.
|
||
|
||
Пользователь обращается к контроллеру и действию посредством маршрута (route).
|
||
Маршрут формируется путем объединения идентификаторов контроллера и действия,
|
||
отделенных косой чертой. Например, маршрут `post/edit` указывает на действие
|
||
`edit` контроллера `PostController` и, по умолчанию, URL `http://hostname/index.php?r=post/edit`
|
||
приведет к вызову именно этих контроллера и действия.
|
||
|
||
> Note|Примечание: По умолчанию маршруты чувствительны к регистру.
|
||
>Начиная с версии 1.0.1 это возможно изменить путем установки свойства
|
||
>[CUrlManager::caseSensitive в конфигурации приложения] равным false.
|
||
>В режиме нечувствительном к регистру убедитесь, что названия директорий,
|
||
>содержащих файлы классов контроллеров написаны в нижнем регистре, а также
|
||
>что [controller map|CWebApplication::controllerMap] и [action map|CController::actions]
|
||
>используют ключи в нижнем регистре.
|
||
|
||
|
||
Создание экземпляра контроллера
|
||
-------------------------------
|
||
Экземпляр контроллера создается, когда [CWebApplication] обрабатывает входящий запрос.
|
||
Получив идентификатор контроллера, приложение использует следующие правила для
|
||
определения класса контроллера и его местоположения:
|
||
|
||
- если установлено свойство [CWebApplication::catchAllRequest], контроллер будет создан
|
||
на основании этого свойства, а контроллер, запрошенный пользователем, будет проигнорирован.
|
||
Как правило, это используется для установки приложения в режим технического обслуживания
|
||
и отображения статической страницы с соответствующим сообщением;
|
||
|
||
- если идентификатор контроллера обнаружен в [CWebApplication::controllerMap], то для
|
||
создания экземпляра контроллера будет использована соответствующая конфигурация контроллера;
|
||
|
||
- если идентификатор контроллера соответствует формату `'path/to/xyz'`, то имя класса
|
||
контроллера определяется как `XyzController`, а соответствующий класс как
|
||
`protected/controllers/path/to/XyzController.php`.
|
||
Например, идентификатор контроллера `admin/user` будет распознан как класс
|
||
контроллера — `UserController` и файл класса —
|
||
`protected/controllers/admin/UserController.php`. Если файл класса не существует,
|
||
будет вызвано исключение [CHttpException] с кодом ошибки 404.
|
||
|
||
В случае использование [модулей](/doc/guide/basics.module) (доступны, начиная с
|
||
версии 1.0.3), процесс описанный выше будет выглядеть несколько иначе. В частности,
|
||
приложение проверит, если идентификатор соответствует контроллеру внутри модуля.
|
||
В случае, если это имеет место, будет создан экземпляр модуля вместе с экземпляром
|
||
контроллера.
|
||
|
||
|
||
Действие
|
||
--------
|
||
Как было упомянуто выше, действие — это метод, имя которого начинается на `action`.
|
||
Более продвинутый способ — создать класс действия и указать контроллеру создавать
|
||
экземпляр этого класса при необходимости. Такой подход позволяет использовать
|
||
действия повторно.
|
||
|
||
|
||
Для создания класса действия необходимо выполнить следующее:
|
||
|
||
~~~
|
||
[php]
|
||
class UpdateAction extends CAction
|
||
{
|
||
public function run()
|
||
{
|
||
// некоторая логика действия
|
||
}
|
||
}
|
||
~~~
|
||
|
||
Чтобы контроллер знал об этом действии, необходимо переопределить метод
|
||
[actions()|CController::actions] в классе контроллера:
|
||
|
||
~~~
|
||
[php]
|
||
class PostController extends CController
|
||
{
|
||
public function actions()
|
||
{
|
||
return array(
|
||
'edit'=>'application.controllers.post.UpdateAction',
|
||
);
|
||
}
|
||
}
|
||
~~~
|
||
|
||
В приведенном коде мы используем псевдоним маршрута `application.controllers.post.UpdateAction`
|
||
для указания на файл класса действия `protected/controllers/post/UpdateAction.php`.
|
||
Создавая действия, основанные на классах, можно организовать приложение в модульном стиле.
|
||
Например, следующая структура директорий может быть использована для расположения кода контроллеров:
|
||
~~~
|
||
protected/
|
||
controllers/
|
||
PostController.php
|
||
UserController.php
|
||
post/
|
||
CreateAction.php
|
||
ReadAction.php
|
||
UpdateAction.php
|
||
user/
|
||
CreateAction.php
|
||
ListAction.php
|
||
ProfileAction.php
|
||
UpdateAction.php
|
||
~~~
|
||
|
||
|
||
Фильтры
|
||
---------------
|
||
Фильтр (filter) – это часть кода, который может выполняться до или после
|
||
выполнения действия контроллера в зависимости от конфигурации. Например, фильтр
|
||
контроля доступа может проверять, аутентифицирован ли пользователь перед тем,
|
||
как будет выполнено запрошенное действие. Фильтр, контролирующий производительность,
|
||
может быть использован для определения времени, затраченного на выполнение действия.
|
||
|
||
Действие может иметь множество фильтров. Фильтры запускаются в том порядке, в котором
|
||
они указаны в списке фильтров, при этом фильтр может предотвратить выполнение
|
||
действия и следующих за ним фильтров.
|
||
|
||
Фильтр может быть определен как метод класса контроллера. Имя метода должно начинаться на `filter`.
|
||
Например, существование метода `filterAccessControl` означает, что определен фильтр `accessControl`.
|
||
Метод фильтра оформляется следующим образом:
|
||
|
||
~~~
|
||
[php]
|
||
public function filterAccessControl($filterChain)
|
||
{
|
||
// для выполнения последующих фильтров и выполнения действия вызовите метод $filterChain->run()
|
||
}
|
||
~~~
|
||
|
||
где `$filterChain` — экземпляр класса [CFilterChain], представляющего собой список
|
||
фильтров, ассоциированных с запрошенным действием. В коде фильтра можно вызвать
|
||
`$filterChain->run()` для того, чтобы продолжить выполнение последующих фильтров и действия.
|
||
|
||
Фильтр также может быть экземпляром класса [CFilter] или его производного.
|
||
Следующий код определяет новый класс фильтра:
|
||
|
||
~~~
|
||
[php]
|
||
class PerformanceFilter extends CFilter
|
||
{
|
||
protected function preFilter($filterChain)
|
||
{
|
||
// код, выполняемый до выполнения действия
|
||
return true; // false — для случая, когда действие не должно быть выполнено
|
||
}
|
||
|
||
protected function postFilter($filterChain)
|
||
{
|
||
// код, выполняемый после выполнения действия
|
||
}
|
||
}
|
||
~~~
|
||
|
||
Для того, чтобы применить фильтр к действию, необходимо переопределить метод
|
||
`CController::filters()`, возвращающий массив конфигураций фильтров. Например:
|
||
|
||
~~~
|
||
[php]
|
||
class PostController extends CController
|
||
{
|
||
…
|
||
public function filters()
|
||
{
|
||
return array(
|
||
'postOnly + edit, create',
|
||
array(
|
||
'application.filters.PerformanceFilter - edit, create',
|
||
'unit'=>'second',
|
||
),
|
||
);
|
||
}
|
||
}
|
||
~~~
|
||
|
||
Данный код определяет два фильтра: `postOnly` и `PerformanceFilter`.
|
||
Фильтр `postOnly` задан как метод (соответствующий метод уже определен в
|
||
[CController]), в то время как `PerformanceFilter` — фильтр на базе класса.
|
||
Псевдоним `application.filters.PerformanceFilter` указывает на файл класса фильтра —
|
||
`protected/filters/PerformanceFilter`. Для конфигурации `PerformanceFilter`
|
||
использован массив, поэтому возможно инициализировать значения свойства фильтра.
|
||
В данном случае свойство `unit` фильтра `PerformanceFilter` будет
|
||
инициализировано значением `'second'`.
|
||
|
||
Используя операторы `'+'` и `'-'` можно указать, к каким действиям должен и
|
||
не должен быть применен фильтр. В приведенном примере `postOnly` должен быть
|
||
применен к действиям `edit` и `create`, а `PerformanceFilter` — ко всем действиям,
|
||
*кроме* `edit` и `create`. Если операторы `'+'` и `'-'` не указаны, фильтр будет
|
||
применен ко всем действиям.
|
||
|
||
<div class="revision">$Id: basics.controller.txt 1263 2009-07-21 19:22:00Z qiang.xue $</div>
|