HTTP-запрос
Nette инкапсулирует HTTP-запрос в объекты с понятным API и одновременно предоставляет санитайзирующий фильтр.
HTTP-запрос представляет собой объект Nette\Http\Request. Если вы работаете с Nette, этот объект автоматически создается фреймворком, и вы можете получить его с помощью внедрения зависимостей. В презентерах достаточно просто вызвать метод $this->getHttpRequest(). Если вы работаете вне Nette Framework, вы можете создать объект с помощью RequestFactory.
Большим преимуществом Nette является то, что при создании объекта он автоматически очищает все входные параметры GET, POST, COOKIE, а также URL от управляющих символов и невалидных UTF-8 последовательностей. С этими данными затем можно безопасно работать дальше. Очищенные данные впоследствии используются в презентерах и формах.
Nette\Http\Request
Этот объект является immutable (неизменяемым). У него нет сеттеров, есть только один так называемый wither withUrl(), который не изменяет объект, а возвращает новый экземпляр с измененным значением.
withUrl (Nette\Http\UrlScript $url): Nette\Http\Request
Возвращает клон с другим URL.
getUrl(): Nette\Http\UrlScript
Возвращает URL запроса как объект UrlScript.
$url = $httpRequest->getUrl(); echo $url; // https://doc.nette.org/cs/?action=edit echo $url->getHost(); // nette.org Внимание: браузеры не отправляют фрагмент на сервер, поэтому $url->getFragment() будет возвращать пустую строку.
getQuery (?string $key=null): string|array|null
Возвращает параметры GET-запроса.
$all = $httpRequest->getQuery(); // возвращает массив всех параметров из URL $id = $httpRequest->getQuery('id'); // возвращает GET-параметр 'id' (или null) getPost (?string $key=null): string|array|null
Возвращает параметры POST-запроса.
$all = $httpRequest->getPost(); // возвращает массив всех параметров из POST $id = $httpRequest->getPost('id'); // возвращает POST-параметр 'id' (или null) getFile (string|string[] $key): Nette\Http\FileUpload|array|null
Возвращает загруженный файл как объект Nette\Http\FileUpload:
$file = $httpRequest->getFile('avatar'); if ($file?->hasFile()) { // был ли загружен какой-либо файл? $file->getUntrustedName(); // имя файла, отправленное пользователем $file->getSanitizedName(); // имя без опасных символов } Для доступа к вложенной структуре укажите массив ключей.
//<input type="file" name="my-form[details][avatar]" multiple> $file = $request->getFile(['my-form', 'details', 'avatar']); Поскольку нельзя доверять данным извне и, следовательно, полагаться на структуру файлов, этот способ безопаснее, чем, например, $request->getFiles()['my-form']['details']['avatar'], который может не сработать.
getFiles(): array
Возвращает дерево всех загруженных файлов в нормализованной структуре, листьями которой являются объекты Nette\Http\FileUpload:
$files = $httpRequest->getFiles(); getCookie (string $key): string|array|null
Возвращает cookie или null, если она не существует.
$sessId = $httpRequest->getCookie('sess_id'); getCookies(): array
Возвращает все cookie.
$cookies = $httpRequest->getCookies(); getMethod(): string
Возвращает HTTP-метод, с которым был сделан запрос.
$httpRequest->getMethod(); // GET, POST, HEAD, PUT isMethod (string $method): bool
Проверяет HTTP-метод, с которым был сделан запрос. Параметр нечувствителен к регистру.
if ($httpRequest->isMethod('GET')) // ... getHeader (string $header): ?string
Возвращает HTTP-заголовок или null, если он не существует. Параметр нечувствителен к регистру.
$userAgent = $httpRequest->getHeader('User-Agent'); getHeaders(): array
Возвращает все HTTP-заголовки как ассоциативный массив.
$headers = $httpRequest->getHeaders(); echo $headers['Content-Type']; isSecured(): bool
Является ли соединение шифрованным (HTTPS)? Для правильной работы может потребоваться настроить прокси.
isSameSite(): bool
Приходит ли запрос с того же (суб)домена и инициирован ли он кликом по ссылке? Nette для обнаружения использует cookie _nss (ранее nette-samesite).
isAjax(): bool
Является ли это AJAX-запросом?
getRemoteAddress(): ?string
Возвращает IP-адрес пользователя. Для правильной работы может потребоваться настроить прокси.
getRemoteHost(): ?string
Возвращает DNS-преобразование IP-адреса пользователя. Для правильной работы может потребоваться настроить прокси.
getBasicCredentials(): ?array
Возвращает учетные данные для Basic HTTP authentication.
[$user, $password] = $httpRequest->getBasicCredentials(); getRawBody(): ?string
Возвращает тело HTTP-запроса.
$body = $httpRequest->getRawBody(); detectLanguage (array $langs): ?string
Определяет язык. В качестве параметра $langs передаем массив языков, которые поддерживает приложение, и она возвращает тот, который предпочел бы видеть браузер посетителя. Это не магия, просто используется заголовок Accept-Language. Если совпадений нет, возвращает null.
// браузер отправляет, например, Accept-Language: cs,en-us;q=0.8,en;q=0.5,sl;q=0.3 $langs = ['hu', 'pl', 'en']; // языки, поддерживаемые приложением echo $httpRequest->detectLanguage($langs); // en RequestFactory
Класс Nette\Http\RequestFactory служит для создания экземпляра Nette\Http\Request, который представляет текущий HTTP-запрос. (Если вы работаете с Nette, объект HTTP-запроса автоматически создается фреймворком.)
$factory = new Nette\Http\RequestFactory; $httpRequest = $factory->fromGlobals(); Метод fromGlobals() создает объект запроса на основе текущих глобальных переменных PHP ($_GET, $_POST, $_COOKIE, $_FILES и $_SERVER). При создании объекта он автоматически очищает все входные параметры GET, POST, COOKIE, а также URL от управляющих символов и невалидных UTF-8 последовательностей, что обеспечивает безопасность при дальнейшей работе с этими данными.
RequestFactory можно сконфигурировать перед вызовом fromGlobals():
- методом
$factory->setBinary()отключите автоматическую очистку входных параметров от управляющих символов и невалидных UTF-8 последовательностей. - методом
$factory->setProxy(...)укажите IP-адрес прокси-сервера, что необходимо для правильного определения IP-адреса пользователя.
RequestFactory позволяет определить фильтры, которые автоматически трансформируют части URL запроса. Эти фильтры удаляют нежелательные символы из URL, которые могут быть туда вставлены, например, из-за неправильной реализации систем комментариев на различных веб-сайтах:
// удаление пробелов из пути $requestFactory->urlFilters['path']['%20'] = ''; // удаление точки, запятой или правой скобки с конца URI $requestFactory->urlFilters['url']['[.,)]$'] = ''; // очистка пути от удвоенных слешей (фильтр по умолчанию) $requestFactory->urlFilters['path']['/{2,}'] = '/'; Первый ключ 'path' или 'url' определяет, к какой части URL применяется фильтр. Второй ключ — это регулярное выражение, которое нужно найти, а значение — это замена, которая будет использована вместо найденного текста.
Загруженные файлы
Метод Nette\Http\Request::getFiles() возвращает массив всех загруженных файлов в нормализованной структуре, листьями которой являются объекты Nette\Http\FileUpload. Они инкапсулируют данные, отправленные элементом формы <input type=file>.
Структура отражает именование элементов в HTML. В простейшем случае это может быть единственный именованный элемент формы, отправленный как:
<input type="file" name="avatar"> В этом случае $request->getFiles() возвращает массив:
[ 'avatar' => /* FileUpload instance */ ] Объект FileUpload создается и в случае, если пользователь не отправил ни одного файла или отправка не удалась. Был ли файл отправлен, возвращает метод hasFile():
$request->getFile('avatar')?->hasFile(); В случае имени элемента, использующего нотацию для массива:
<input type="file" name="my-form[details][avatar]"> возвращаемое дерево выглядит так:
[ 'my-form' => [ 'details' => [ 'avatar' => /* FileUpload instance */ ], ], ] Можно создать и массив файлов:
<input type="file" name="my-form[details][avatars][]" multiple> В таком случае структура выглядит так:
[ 'my-form' => [ 'details' => [ 'avatars' => [ 0 => /* FileUpload instance */, 1 => /* FileUpload instance */, 2 => /* FileUpload instance */, ], ], ], ] Доступ к индексу 1 вложенного массива лучше всего получить так:
$file = $request->getFile(['my-form', 'details', 'avatars', 1]); if ($file instanceof FileUpload) { // ... } Поскольку нельзя доверять данным извне и, следовательно, полагаться на структуру файлов, этот способ безопаснее, чем, например, $request->getFiles()['my-form']['details']['avatars'][1], который может не сработать.
Обзор методов FileUpload
hasFile(): bool
Возвращает true, если пользователь загрузил какой-либо файл.
isOk(): bool
Возвращает true, если файл был загружен успешно.
getError(): int
Возвращает код ошибки при загрузке файла. Это одна из констант UPLOAD_ERR_XXX. В случае, если загрузка прошла успешно, возвращает UPLOAD_ERR_OK.
move (string $dest): void
Перемещает загруженный файл в новое местоположение. Если целевой файл уже существует, он будет перезаписан.
$file->move('/path/to/files/name.ext'); getContents(): ?string
Возвращает содержимое загруженного файла. В случае, если загрузка не была успешной, возвращает null.
getContentType(): ?string
Определяет MIME content type загруженного файла на основе его сигнатуры. В случае, если загрузка не была успешной или определение не удалось, возвращает null.
Требует PHP-расширение fileinfo.
getUntrustedName(): string
Возвращает оригинальное имя файла, как его отправил браузер.
Не доверяйте значению, возвращаемому этим методом. Клиент мог отправить вредоносное имя файла с намерением повредить или взломать ваше приложение.
getSanitizedName(): string
Возвращает очищенное (sanitized) имя файла. Содержит только ASCII-символы [a-zA-Z0-9.-]. Если имя не содержит таких символов, возвращает 'unknown'. Если файл является изображением в формате JPEG, PNG, GIF, WebP или AVIF, возвращает и правильное расширение.
Требует PHP-расширение fileinfo.
getSuggestedExtension(): ?string
Возвращает подходящее расширение файла (без точки), соответствующее определенному MIME-типу.
Требует PHP-расширение fileinfo.
getUntrustedFullPath(): string
Возвращает оригинальный путь к файлу, как его отправил браузер при загрузке папки. Полный путь доступен только в PHP 8.1 и выше. В предыдущих версиях этот метод возвращает оригинальное имя файла.
Не доверяйте значению, возвращаемому этим методом. Клиент мог отправить вредоносное имя файла с намерением повредить или взломать ваше приложение.
getSize(): int
Возвращает размер загруженного файла. В случае, если загрузка не была успешной, возвращает 0.
getTemporaryFile(): string
Возвращает путь к временному местоположению загруженного файла. В случае, если загрузка не была успешной, возвращает ''.
isImage(): bool
Возвращает true, если загруженный файл является изображением в формате JPEG, PNG, GIF, WebP или AVIF. Определение происходит на основе его сигнатуры и не проверяется целостность всего файла. Не повреждено ли изображение, можно узнать, например, попытавшись его загрузить.
Требует PHP-расширение fileinfo.
getImageSize(): ?array
Возвращает пару [ширина, высота] с размерами загруженного изображения. В случае, если загрузка не была успешной или это не валидное изображение, возвращает null.
toImage(): Nette\Utils\Image
Загружает изображение как объект Image. В случае, если загрузка не была успешной или это не валидное изображение, выбрасывает исключение Nette\Utils\ImageException.