Компонент 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, остаются без изменений.