Компонент Symfony HttpFoundation содержит очень полезный класс Response. Объект класса Response содержит всю информацию, которая должна быть отправлена обратно клиенту из данного запроса: содержимое ответа, заголовки и т.д.
Конструктор класса Response принимает до трех аргументов: содержимое ответа, код состояния и массив заголовков HTTP:
use Symfony\Component\HttpFoundation\Response;
$response = new Response(
'Content',
Response::HTTP_OK,
['content-type' => 'text/html']
);
Этой информацией также можно манипулировать после создания объекта Response:
$response->setContent('Hello World');
// the headers public attribute is a ResponseHeaderBag
$response->headers->set('Content-Type', 'text/plain');
$response->setStatusCode(Response::HTTP_NOT_FOUND);
При установке Content-Type Ответа вы можете установить кодировку, но лучше установить ее с помощью метода setCharset():
$response->setCharset('ISO-8859-1');
Обратите внимание, что по умолчанию Symfony предполагает, что ваши ответы закодированы в UTF-8.
Отправка Response в компоненте HttpFoundation.
Перед отправкой ответа вы можете дополнительно вызвать метод prepare(), чтобы исправить любую несовместимость со спецификацией HTTP (например, неправильный заголовок Content-Type):
$response->prepare($request);
Отправка ответа клиенту осуществляется путем вызова метода send():
$response->send();
Установка куки в Response Symfony.
Куки ответа можно манипулировать через публичный атрибут headers:
use Symfony\Component\HttpFoundation\Cookie;
$response->headers->setCookie(Cookie::create('foo', 'bar'));
Метод setCookie() принимает экземпляр Cookie в качестве аргумента.
Вы можете удалить cookie с помощью метода clearCookie().
Обратите внимание, что вы можете создать объект Cookie из необработанного значения заголовка, используя fromString().
Управление HTTP-кешем.
Класс Response имеет богатый набор методов для управления заголовками HTTP, связанными с кешем:
- setPublic();
- setPrivate();
- expire();
- setExpires();
- setMaxAge();
- setSharedMaxAge();
- setTtl();
- setClientTtl();
- setLastModified();
- setEtag();
- setVary();
Методы setExpires(), setLastModified() и setDate() принимают любой объект, который реализует \DateTimeInterface, включая неизменяемые объекты даты.
Метод setCache() может использоваться для установки наиболее часто используемой информации кэша в одном вызове метода:
$response->setCache([
'etag' => 'abcdef',
'last_modified' => new \DateTime(),
'max_age' => 600,
's_maxage' => 600,
'private' => false,
'public' => true,
'immutable' => true,
]);
Чтобы проверить, соответствуют ли валидаторы ответа (ETag, Last-Modified) условному значению, указанному в клиентском запросе, используйте метод isNotModified():
if ($response->isNotModified($request)) {
$response->send();
}
Если Response не изменен, он устанавливает код состояния равным 304 и удаляет фактическое содержимое ответа.
Перенаправление (redirect) пользователя (user).
use Symfony\Component\HttpFoundation\RedirectResponse;
$response = new RedirectResponse('http://example.com/');
Streaming a response.
Класс StreamedResponse позволяет передавать ответ обратно клиенту. Содержимое ответа представляется вызываемым PHP вместо строки:
use Symfony\Component\HttpFoundation\StreamedResponse;
$response = new StreamedResponse();
$response->setCallback(function () {
var_dump('Hello World');
flush();
sleep(2);
var_dump('Hello World');
flush();
});
$response->send();
Функция flush () не очищает буферизацию. Если ob_start () был вызван раньше или включена опция output_buffering php.ini, вы должны вызвать ob_flush () перед flush ().
Кроме того, PHP не единственный слой, который может буферизовать вывод. Ваш веб-сервер также может буферизоваться в зависимости от его конфигурации. Некоторые серверы, такие как nginx, позволяют отключить буферизацию на уровне конфигурации или добавив специальный HTTP-заголовок в ответ:
// disables FastCGI buffering in nginx only for this response
$response->headers->set('X-Accel-Buffering', 'no')
Создание response типа JSON.
Любой тип ответа может быть создан с помощью класса Response путем установки правильного содержимого и заголовков. Ответ JSON может выглядеть так:
use Symfony\Component\HttpFoundation\Response;
$response = new Response();
$response->setContent(json_encode([
'data' => 123,
]));
$response->headers->set('Content-Type', 'application/json');
В компоненте Symfony HttpFoundation существует также полезный класс JsonResponse, который может сделать это еще проще:
use Symfony\Component\HttpFoundation\JsonResponse;
// if you know the data to send when creating the response
$response = new JsonResponse(['data' => 123]);
// if you don't know the data to send when creating the response
$response = new JsonResponse();
// ...
$response->setData(['data' => 123]);
// if the data to send is already encoded in JSON
$response = JsonResponse::fromJsonString('{ "data": 123 }');
Класс JsonResponse устанавливает заголовок Content-Type в значение application/json и при необходимости кодирует ваши данные в JSON.
Чтобы избежать XSSI JSON Hijacking, вы должны передавать ассоциативный массив как самый внешний массив в JsonResponse, а не индексированный массив, чтобы конечный результат был объектом (например, {«object»: «not inside the array»}) вместо массив (например, [{«объект»: «внутри массива»}]). Прочитайте рекомендации OWASP для получения дополнительной информации.
Только методы, которые отвечают на запросы GET, уязвимы для XSSI ‘JSON Hijacking’. Методы, отвечающие на запросы POST, остаются без изменений.