Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
a24cab54
Commit
a24cab54
authored
Nov 13, 2014
by
Vadim Belorussov
Committed by
Alexander Makarov
Nov 27, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Translated guide/runtime-responses.md into Russian
parent
402d58cf
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
258 additions
and
0 deletions
+258
-0
runtime-responses.md
docs/guide-ru/runtime-responses.md
+258
-0
No files found.
docs/guide-ru/runtime-responses.md
0 → 100644
View file @
a24cab54
Ответы
=========
Когда приложение заканчивает обработку
[
запроса
](
runtime-requests.md
)
, оно генерирует объект
[
[yii\web\Response|ответа
]
]
и отправляет его конечному пользователю. Объект ответа содержит такие данные, как HTTP-код состояния, HTTP-заголовки и тело ответа.
По существу, конечная цель разработки Web-приложения — создание таких объектов ответа на различные запросы.
В большинстве случаев вам придется иметь дело в основном с
[
компонентом приложения
](
structure-application-components.md
)
`response`
,
который по умолчанию является экземпляром класса
[
[yii\web\Response
]
]. Однако Yii также позволяет вам создавать собственные объекты ответа
и отправлять их конечным пользователям, как будет рассмотрено ниже.
В данном разделе мы опишем, как составлять ответы и отправлять их конечным пользователям.
## Код состояния <a name="status-code"></a>
Одна из первых вещей, которые вы делаете при построении ответа, — это определение того, был ли успешно обработан запрос.
Это делается путём установки свойства
[
[yii\web\Response::statusCode
]
], которое может принимать значение одного из валидных
[
HTTP-кодов состояния
](
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
)
. Например, чтобы показать, что запрос был
успешно обработан, вы можете установить значение кода состояния равным 200, вот так:
```
php
Yii
::
$app
->
response
->
statusCode
=
200
;
```
Однако в большинстве случаев вам не нужно явно устанавливать значение кода состояния. Дело в том, что значение свойства
[
[yii\web\Response::statusCode
]
] по умолчанию равно 200. А если вам нужно показать, что запрос не имел успеха, вы можете
выбросить соответствующее HTTP-исключение, как показано здесь:
```
php
throw
new
\yii\web\NotFoundHttpException
;
```
Когда
[
обработчик ошибок
](
runtime-handling-errors.md
)
поймает исключение, он извлечёт код состояния
из исключения и назначит его ответу. Исключение
[
[yii\web\NotFoundHttpException
]
] в коде выше
связано с HTTP-кодом состояния 404. В Yii предопределены следующие HTTP-исключения:
*
[
[yii\web\BadRequestHttpException
]
]: код состояния 400.
*
[
[yii\web\ConflictHttpException
]
]: код состояния 409.
*
[
[yii\web\ForbiddenHttpException
]
]: код состояния 403.
*
[
[yii\web\GoneHttpException
]
]: код состояния 410.
*
[
[yii\web\MethodNotAllowedHttpException
]
]: код состояния 405.
*
[
[yii\web\NotAcceptableHttpException
]
]: код состояния 406.
*
[
[yii\web\NotFoundHttpException
]
]: код состояния 404.
*
[
[yii\web\ServerErrorHttpException
]
]: код состояния 500.
*
[
[yii\web\TooManyRequestsHttpException
]
]: код состояния 429.
*
[
[yii\web\UnauthorizedHttpException
]
]: код состояния 401.
*
[
[yii\web\UnsupportedMediaTypeHttpException
]
]: код состояния 415.
Если в вышеприведённом списке нет исключения, которое вы хотите выбросить, вы можете создать его, расширив класс
[
[yii\web\HttpException
]
], или выбросить его напрямую с кодом состояния, например:
```
php
throw
new
\yii\web\HttpException
(
402
);
```
## HTTP-заголовки <a name="http-headers"></a>
Вы можете отправлять HTTP-заголовки, управляя
[
[yii\web\Response::headers|набором заголовков
]
] компонента
`response`
.
Например:
```
php
$headers
=
Yii
::
$app
->
response
->
headers
;
// добавить заголовок Pragma. Уже имеющиеся Pragma-заголовки НЕ будут перезаписаны.
$headers
->
add
(
'Pragma'
,
'no-cache'
);
// установить заголовок Pragma. Любые уже имеющиеся Pragma-заголовки будут сброшены.
$headers
->
set
(
'Pragma'
,
'no-cache'
);
// удалить заголовок (или заголовки) Pragma и вернуть значения удалённых Pragma-заголовков в массиве
$values
=
$headers
->
remove
(
'Pragma'
);
```
> Информация: названия заголовков не чувствительны к регистру символов. Заново зарегистрированные заголовки не отсылаются пользователю
до тех пор, пока не будет вызван метод
[
[yii\web\Response::send()
]
].
## Тело ответа <a name="response-body"></a>
Большинство ответов должны иметь тело, несущее содержимое, которое вы хотите показать конечным пользователям.
Если у вас уже имеется отформатированная строка тела, вы можете назначить её свойству
[
[yii\web\Response::content
]
]
объекта запроса. Например:
```
php
Yii
::
$app
->
response
->
content
=
'hello world!'
;
```
Если ваши данные перед отправкой конечным пользователям нужно привести к определённому формату, вам следует установить значения
двух свойств:
[
[yii\web\Response::format|формат
]
] и
[
[yii\web\Response::data|данные
]
]. Свойство
[
[yii\web\Response::format|формат
]
]
определяет, в каком формате следует возвращать
[
[yii\web\Response::data|данные
]
]. Например:
```
php
$response
=
Yii
::
$app
->
response
;
$response
->
format
=
\yii\web\Response
::
FORMAT_JSON
;
$response
->
data
=
[
'message'
=>
'hello world'
];
```
Yii из коробки имеет поддержку следующих форматов, каждый из которых реализован классом
[
[yii\web\ResponseFormatterInterface|форматтера
]
].
Вы можете настроить эти форматтеры или добавить новые путём настройки свойства
[
[yii\web\Response::formatters
]
].
*
[
[yii\web\Response::FORMAT_HTML|HTML
]
]: реализуется классом
[
[yii\web\HtmlResponseFormatter
]
].
*
[
[yii\web\Response::FORMAT_XML|XML
]
]: реализуется классом
[
[yii\web\XmlResponseFormatter
]
].
*
[
[yii\web\Response::FORMAT_JSON|JSON
]
]: реализуется классом
[
[yii\web\JsonResponseFormatter
]
].
*
[
[yii\web\Response::FORMAT_JSONP|JSONP
]
]: реализуется классом
[
[yii\web\JsonResponseFormatter
]
].
Хотя тело запроса может быть явно установлено показанным выше способом, в большинстве случаев вы можете устанавливать его неявно
через возвращаемое значение методов
[
действий
](
structure-controllers.md
)
. Типичный пример использования:
```
php
public
function
actionIndex
()
{
return
$this
->
render
(
'index'
);
}
```
Действие
`index`
в коде выше возвращает результат рендеринга представления
`index`
. Возвращаемое значение будет взято
компонентом
`response`
, отформатировано и затем отправлено конечным пользователям.
Так как по умолчанию форматом ответа является
[
[yii\web\Response::FORMAT_HTML|HTML
]
], в методе действия достаточно вернуть строку.
Если вы хотите использовать другой формат ответа, нужно сначала установить его перед отправкой данных. Например:
```
php
public
function
actionInfo
()
{
\Yii
::
$app
->
response
->
format
=
\yii\web\Response
::
FORMAT_JSON
;
return
[
'message'
=>
'hello world'
,
'code'
=>
100
,
];
}
```
Как было сказано выше, кроме использования компонента приложения
`response`
по умолчанию вы также можете создавать свои
объекты ответа и отправлять их конечным пользователям. Вы можете сделать это, возвращая такой объект в методе действия, например:
```
php
public
function
actionInfo
()
{
return
\Yii
::
createObject
([
'class'
=>
'yii\web\Response'
,
'format'
=>
\yii\web\Response
::
FORMAT_JSON
,
'data'
=>
[
'message'
=>
'hello world'
,
'code'
=>
100
,
],
]);
}
```
> Примечание: создавая собственные объекты ответов, вы не сможете воспользоваться конфигурацией компонента `response`,
настроенной вами в конфигурации приложения. Тем не менее, вы можете воспользоваться
[
внедрением зависимости
](
concept-di-container.md
)
, чтобы применить общую конфигурацию к вашим новым объектам ответа.
## Перенаправление браузера <a name="browser-redirection"></a>
Перенаправление браузера основано на отправке HTTP-заголовка
`Location`
. Так как данная функция широко используется, Yii предоставляет
некоторые особые средства для её поддержки.
Вы можете перенаправить браузер пользователя на URL-адрес, вызвав метод
[
[yii\web\Response::redirect()
]
]. Этот метод
устанавливает значение заголовка
`Location`
равным указанному URL-адресу и возвращает сам объект ответа. В методе действия
вы можете вызвать короткую версию этого метода —
[
[yii\web\Controller::redirect()
]
]. Например:
```
php
public
function
actionOld
()
{
return
$this
->
redirect
(
'http://example.com/new'
,
301
);
}
```
В приведённом выше коде метод действия возвращает результат метода
`redirect()`
. Как говорилось выше, объект ответа,
возвращаемый методом действия, будет использоваться как ответ, отправляемый конечным пользователям.
В коде, находящемся не внутри методов действий, вам следует вызывать
[
[yii\web\Response::redirect()
]
], а непосредственно после него
— метод
[
[yii\web\Response::send()
]
], чтобы быть уверенным, что к ответу не будет добавлено никакое нежелательное содержимое.
```
php
\Yii
::
$app
->
response
->
redirect
(
'http://example.com/new'
,
301
)
->
send
();
```
> Информация: По умолчанию метод [[yii\web\Response::redirect()]] устанавливает код состояния ответа равным 302, сообщая
браузеру, что запрашиваемый ресурс
*временно*
находится по другому URI-адресу. Вы можете передать код состояния
301, чтобы сообщить браузеру, что ресурс перемещён
*навсегда*
.
Если текущий запрос является AJAX-запросом, отправка заголовка
`Location`
не заставит браузер автоматически
осуществить перенаправление. Чтобы решить эту задачу, метод
[
[yii\web\Response::redirect()
]
] устанавливает значение заголовка
`X-Redirect`
равным URL-адресу перенаправления. На стороне клиента вы можете написать JavaScript-код для чтения значения этого заголовка и
перенаправления браузера соответственно.
> Информация: Yii поставляется с JavaScript-файлом `yii.js`, который предоставляет набор часто используемых JavaScript-инструментов,
включая и перенаправление браузера на основе заголовка
`X-Redirect`
. Следовательно, если вы используете этот JavaScript-файл
(зарегистрировав пакет ресурсов
[
[yii\web\YiiAsset
]
]), вам не нужно писать никакого кода для поддержки AJAX-перенаправления.
## Отправка файлов <a name="sending-files"></a>
Как и перенаправление браузера, отправка файлов является ещё одной возможностью, основанной на специальных HTTP-заголовках. Yii предоставляет
набор методов для поддержки различных потребностей по отправке файлов. У них всех есть встроенная поддержка HTTP-заголовка диапазона.
*
[
[yii\web\Response::sendFile()
]
]: отправляет клиенту существующий файл.
*
[
[yii\web\Response::sendContentAsFile()
]
]: отправляет клиенту текстовую строку как файл.
*
[
[yii\web\Response::sendStreamAsFile()
]
]: отправляет клиенту существующий файловый поток как файл.
Эти методы имеют одинаковую сигнатуру и возвращают объект ответа как результат. Если отправляемый файл
очень велик, вам следует рассмотреть использование метода
[
[yii\web\Response::sendStreamAsFile()
]
], так как он более
эффективно использует оперативную память. Следующий пример показывает, как отправить файл в действии контроллера:
```
php
public
function
actionDownload
()
{
return
\Yii
::
$app
->
response
->
sendFile
(
'path/to/file.txt'
);
}
```
При вызове метода отправки файла извне методов действий вам следует также вызвать сразу после него
метод
[
[yii\web\Response::send()
]
], чтобы быть уверенным, что к ответу не будет добавлено никакое нежелательное содержимое.
```
php
\Yii
::
$app
->
response
->
sendFile
(
'path/to/file.txt'
)
->
send
();
```
Некоторые Web-серверы поддерживают особый режим отправки файлов, который называется
*X-Sendfile*
. Идея в том, чтобы
перенаправить запрос файла на Web-сервер, который будет непосредственно предоставлять файл. В результате Web-приложение
может завершиться раньше, тогда как Web-сервер ещё пересылает файл. Чтобы использовать эту возможность, вы можете вызвать
метод
[
[yii\web\Response::xSendFile()
]
]. Следующий список обобщает шаги по включению возможности
`X-Sendfile`
для некоторых популярных Web-серверов:
-
Apache:
[
X-Sendfile
](
http://tn123.org/mod_xsendfile
)
-
Lighttpd v1.4:
[
X-LIGHTTPD-send-file
](
http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file
)
-
Lighttpd v1.5:
[
X-Sendfile
](
http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file
)
-
Nginx:
[
X-Accel-Redirect
](
http://wiki.nginx.org/XSendfile
)
-
Cherokee:
[
X-Sendfile and X-Accel-Redirect
](
http://www.cherokee-project.com/doc/other_goodies.html#x-sendfile
)
## Отправка ответа <a name="sending-response"></a>
Содержимое ответа не отправляется пользователю до тех пор, пока не будет вызван метод
[
[yii\web\Response::send()
]
].
По умолчанию данный метод будет вызван автоматически в конце метода
[
[yii\base\Application::run()
]
]. Однако вы можете
явно вызвать этот метод, чтобы ответ был отправлен немедленно.
При отправке ответа метод
[
[yii\web\Response::send()
]
] выполняет следующие шаги:
1.
Инициируется событие
[
[yii\web\Response::EVENT_BEFORE_SEND
]
].
2.
Вызывается метод
[
[yii\web\Response::prepare()
]
] для форматирования
[
[yii\web\Response::data|данных ответа
]
] в
[
[yii\web\Response::content|содержимое ответа
]
].
3.
Инициируется событие
[
[yii\web\Response::EVENT_AFTER_PREPARE
]
].
4.
Вызывается метод
[
[yii\web\Response::sendHeaders()
]
] для отправки зарегистрированных HTTP-заголовков.
5.
Вызывается метод
[
[yii\web\Response::sendContent()
]
] для отправки содержимого тела ответа.
6.
Инициируется событие
[
[yii\web\Response::EVENT_AFTER_SEND
]
].
Если метод
[
[yii\web\Response::send()
]
] уже был однажды вызван, любой последующий вызов этого метода будет проигнорирован.
Это означает, что если ответ уже отправлен, вы уже ничего не сможете добавить к нему.
Как видно, метод
[
[yii\web\Response::send()
]
] инициирует несколько полезных событий. Реагируя на
эти события, становится возможным настраивать или декорировать ответ.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment