Компонент HttpFoundation определяет объектно-ориентированный уровень для HTTP.
В PHP запрос представлен некоторыми глобальными переменными ($ _GET, $ _POST, $ _FILES, $ _COOKIE, $ _SESSION, …), и ответ генерируется некоторыми функциями (echo, header (), setcookie (), …).
Компонент Symfony HttpFoundation заменяет эти глобальные переменные и функции PHP отдельным объектно-ориентированным слоем.
Создание Request
Самый распространенный способ создания Request — это создать его на основе текущих глобальных переменных PHP с помощью createFromGlobals():
use Symfony\Component\HttpFoundation\Request; $request = Request::createFromGlobals();
Это почти эквивалентно более многословному, но и более гибкому вызову методу __construct():
$request = new Request( $_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER );
Получение доступа к данным в объекте Request Symfony
Объект Request содержит информацию о клиентском запросе. К этой информации можно получить доступ через несколько общедоступных свойств:
- request: эквивалент $ _POST;
- query: эквивалент $ _GET ($request->query->get(‘name’));
- cookies: эквивалент $ _COOKIE;
- attributes: нет эквивалента — используется вашим приложением для хранения других данных (см. ниже);
- files: эквивалент $ _FILES;
- server: эквивалент $ _SERVER;
- headers: в основном эквивалентны подмножеству $ _SERVER ($request->headers->get(‘User-Agent’)).
Каждое свойство является экземпляром ParameterBag (или подклассом), который является классом содержащим данные:
- request: ParameterBag;
- query: ParameterBag;
- cookies: ParameterBag;
- attributes: ParameterBag;
- files: FileBag;
- server: ServerBag;
- headers: HeaderBag.
Все экземпляры ParameterBag имеют методы для извлечения и обновления своих данных:
- all() Возвращает параметры.
- keys() Возвращает ключи параметров.
- replace() Заменяет текущие параметры новым набором.
- add() Добавляет параметры.
- get() Возвращает параметр по имени.
- set() Устанавливает параметр по имени.
- has() Возвращает true, если параметр определен.
- remove() Удаляет параметр.
Экземпляр ParameterBag также имеет несколько методов для фильтрации входных значений:
- getAlpha() Возвращает буквенные символы значения параметра;
- getAlnum() Возвращает буквенные символы и цифры значения параметра;
- getBoolean() Возвращает значение параметра, преобразованное в логическое значение;
- getDigits() Возвращает цифры значения параметра;
- getInt() Возвращает значение параметра, преобразованное в целое число;
- filter() Фильтрует параметр с помощью функции PHP filter_var.
Все получатели принимают до двух аргументов: первый — это имя параметра, а второй — значение по умолчанию, которое возвращается, если параметр не существует:
// the query string is '?foo=bar' $request->query->get('foo'); // returns 'bar' $request->query->get('bar'); // returns null $request->query->get('bar', 'baz'); // returns 'baz'
Когда PHP импортирует запрос, он обрабатывает параметры запроса, такие как foo[bar]=baz особым образом, так как создает массив. Таким образом, вы можете получить параметр foo и получить обратно массив с элементом bar:
// the query string is '?foo[bar]=baz' $request->query->get('foo'); // returns ['bar' => 'baz'] $request->query->get('foo[bar]'); // returns null $request->query->get('foo')['bar']; // returns 'baz'
Благодаря публичному свойству attributes вы можете хранить дополнительные данные в запросе, который также является экземпляром ParameterBag. Это в основном используется для прикрепления информации, которая относится к Request и к которой необходимо получить доступ из разных точек вашего приложения.
Наконец, необработанные данные, отправленные с телом запроса, могут быть доступны с помощью getContent():
$content = $request->getContent();
Например, это может быть полезно для обработки строки JSON, отправленной приложению удаленной службой с использованием метода HTTP POST.
Идентификация Request.
В вашем приложении вам нужен способ идентифицировать запрос; в большинстве случаев это делается через «информацию о пути» запроса, к которой можно получить доступ через метод getPathInfo():
// for a request to http://example.com/blog/index.php/pqost/hello-world // the path info is "/post/hello-world" $request->getPathInfo();
Имитация Request
Вместо того чтобы создавать запрос на основе глобальных переменных PHP, вы также можете смоделировать запрос:
$request = Request::create( '/hello-world', 'GET', ['name' => 'Fabien'] );
Метод create() создает запрос на основе URI, метода и некоторых параметров (параметров запроса query или запроса request в зависимости от метода HTTP); и, конечно, вы также можете переопределить все другие переменные (по умолчанию Symfony создает разумные значения по умолчанию для всех глобальных переменных PHP).
Основываясь на таком запросе, вы можете переопределить глобальные переменные PHP с помощью overrideGlobals():
$request->overrideGlobals();
Вы также можете дублировать существующий запрос с помощью duplicate() или изменить набор параметров одним вызовом initialize().
Доступ к сессии запроса Request.
Если у вас есть сеанс, прикрепленный к запросу, вы можете получить к нему доступ через метод getSession(); метод hasPreviousSession() сообщает вам, содержит ли запрос сеанс, который был запущен в одном из предыдущих запросов.
Обработка заголовков запроса HTTP в Symfony.
Обработка заголовков HTTP не является тривиальной задачей из-за экранирования и обработки пустого пространства их содержимого. Symfony предоставляет класс HeaderUtils, который абстрагирует эту сложность и определяет некоторые методы для наиболее распространенных задач:
use Symfony\Component\HttpFoundation\HeaderUtils; // Splits an HTTP header by one or more separators HeaderUtils::split('da, en-gb;q=0.8', ',;'); // => [['da'], ['en-gb','q=0.8']] // Combines an array of arrays into one associative array HeaderUtils::combine([['foo', 'abc'], ['bar']]); // => ['foo' => 'abc', 'bar' => true] // Joins an associative array into a string for use in an HTTP header HeaderUtils::toString(['foo' => 'abc', 'bar' => true, 'baz' => 'a b c'], ','); // => 'foo=abc, bar, baz="a b c"' // Encodes a string as a quoted string, if necessary HeaderUtils::quote('foo "bar"'); // => '"foo \"bar\""' // Decodes a quoted string HeaderUtils::unquote('"foo \"bar\""'); // => 'foo "bar"'
Доступ в Symfony к данным заголовковAccept- *
Вы можете получить доступ к основным данным, извлеченным из заголовков Accept- *, используя следующие методы:
- getAcceptableContentTypes() Возвращает список принятых типов контента, упорядоченных по убыванию качества.
- getLanguages() Возвращает список принятых языков, упорядоченных по убыванию качества.
- getCharsets() Возвращает список принятых кодировок, отсортированных по убыванию качества.
- getEncodings() Возвращает список принятых кодировок, упорядоченных по убыванию качества.
Если вам нужно получить полный доступ к проанализированным данным из Accept, Accept-Language, Accept-Charset или Accept-Encoding, вы можете использовать служебный класс AcceptHeader:
use Symfony\Component\HttpFoundation\AcceptHeader; $acceptHeader = AcceptHeader::fromString($request->headers->get('Accept')); if ($acceptHeader->has('text/html')) { $item = $acceptHeader->get('text/html'); $charset = $item->getAttribute('charset', 'utf-8'); $quality = $item->getQuality(); } // Accept header items are sorted by descending quality $acceptHeaders = AcceptHeader::fromString($request->headers->get('Accept')) ->all();
Значения по умолчанию, которые могут быть дополнительно включены в заголовки Accept- *, также поддерживаются:
$acceptHeader = 'text/plain;q=0.5, text/html, text/*;q=0.8, */*;q=0.3'; $accept = AcceptHeader::fromString($acceptHeader); $quality = $accept->get('text/xml')->getQuality(); // $quality = 0.8 $quality = $accept->get('application/xml')->getQuality(); // $quality = 0.3
Анонимизация IP-адресов в Symfony Request.
Все более распространенная потребность приложений в соблюдении правил защиты пользователей заключается в анонимизации IP-адресов перед их регистрацией и хранением в целях анализа. Используйте метод anonymize() из IpUtils, чтобы сделать это:
use Symfony\Component\HttpFoundation\IpUtils; $ipv4 = '123.234.235.236'; $anonymousIpv4 = IPUtils::anonymize($ipv4); // $anonymousIpv4 = '123.234.235.0' $ipv6 = '2a01:198:603:10:396e:4789:8e99:890f'; $anonymousIpv6 = IPUtils::anonymize($ipv6); // $anonymousIpv6 = '2a01:198:603:10::'
Переопределение Request
Класс Request не должен быть переопределен, поскольку это объект данных, представляющий сообщение HTTP. Но при переходе от устаревшей системы может помочь добавление методов или изменение поведения по умолчанию. В этом случае зарегистрируйте вызываемый PHP, который может создать экземпляр вашего класса Request:
use App\Http\SpecialRequest; use Symfony\Component\HttpFoundation\Request; Request::setFactory(function ( array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null ) { return new SpecialRequest( $query, $request, $attributes, $cookies, $files, $server, $content ); }); $request = Request::createFromGlobals();