HTTP-запрос
Nette инкапсулирует HTTP-запрос в объекты с понятным API, обеспечивая при этом фильтр санации.
HTTP-запрос – это объект Nette\Http\Request, который вы получаете,
передавая его с помощью инъекции зависимостей. В
презентаторах просто вызывайте $httpRequest = $this->getHttpRequest()
.
Важно то, что Nette при создании этого объекта очищает все входные параметры GET, POST и COOKIE, а также URL от управляющих символов и недопустимых последовательностей UTF-8. Поэтому вы можете спокойно продолжать работу с данными. Очищенные данные затем используются в презентаторах и формах.
Nette\Http\Request
Этот объект является неизменяемым. У него нет сеттеров, есть только
один так называемый wither withUrl()
, который не изменяет объект, а
возвращает новый экземпляр с измененным значением.
withUrl (Nette\Http\UrlScript $url): Nette\Http\Request
Возвращает клон с другим URL.
getUrl(): Nette\Http\UrlScript
Возвращает URL запроса в виде объекта UrlScript.
$url = $httpRequest->getUrl();
echo $url; // https://nette.org/en/documentation?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, с помощью которого был сделан запрос.
echo $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(): ?string
Возвращает учетные данные базовой HTTP-аутентификации.
[$user, $password] = $httpRequest->getBasicCredentials();
getRawBody(): ?string
Возвращает тело HTTP-запроса:
$body = $httpRequest->getRawBody();
detectLanguage (array $langs): ?string
Определяет язык. В качестве параметра $lang
мы передаем массив
языков, которые поддерживает приложение, и он возвращает тот, который
предпочитает браузер. Это не магия, метод просто использует заголовок
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
Объект текущего HTTP-запроса создается с помощью Nette\Http\RequestFactory. Если вы пишете приложение, которое не использует DI-контейнер, вы создаете запрос следующим образом:
$factory = new Nette\Http\RequestFactory;
$httpRequest = $factory->fromGlobals();
RequestFactory может быть сконфигурирован перед вызовом fromGlobals()
. Мы
можем отключить всю санацию входных параметров от недопустимых
последовательностей UTF-8 с помощью $factory->setBinary()
. А также
настроить прокси-сервер, что важно для правильного определения
IP-адреса пользователя с помощью $factory->setProxy(...)
.
Очистить URL от символов, которые могут попасть в них из-за плохо реализованных систем комментариев на различных других сайтах, можно с помощью фильтров:
// удалите пробелы из пути
$requestFactory->urlFilters['path']['%20'] = '';
// удалите точку, запятую или правую круглую скобку в конце URL-адреса
$requestFactory->urlFilters['url']['['[.,)]$'] = '';
// очистить путь от дублирующихся слешей (фильтр по умолчанию)
$requestFactory->urlFilters['path']['/{2,}'] = '/';
Загруженные файлы
Метод Nette\Http\Request::getFiles()
возвращает дерево загруженных файлов в
нормализованной структуре, каждый лист которого является экземпляром
Nette\Http\FileUpload. Эти объекты
инкапсулируют данные, представленные элементом <input type=file>
элементом формы.
Структура отражает именование элементов в HTML. В простейшем примере это может быть один именованный элемент формы, представленный как:
<input type="file" name="avatar">
В этом случае $request->getFiles()
возвращает массив:
[
'avatar' => /* FileUpload instance */
]
Объект FileUpload
создается, даже если пользователь не загрузил ни
одного файла или загрузка не удалась. Метод hasFile()
возвращает true,
если файл был отправлен:
$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)
Перемещает загруженный файл в новое место. Если файл назначения уже существует, он будет перезаписан.
$file->move('/path/to/files/name.ext');
getContents(): ?string
Возвращает содержимое загруженного файла. Если загрузка не была
успешной, возвращается null
.
getContentType(): ?string
Определяет MIME-тип содержимого загружаемого файла на основе его
сигнатуры. Если загрузка не была успешной или определение не удалось,
возвращается null
.
Требуется расширение PHP fileinfo
.
getUntrustedName(): string
Возвращает исходное имя файла, переданное браузером.
Не доверяйте значению, возвращаемому этим методом. Клиент может отправить вредоносное имя файла с намерением испортить или взломать ваше приложение.
getSanitizedName(): string
Возвращает санированное имя файла. Оно содержит только символы ASCII
[a-zA-Z0-9.-]
. Если имя не содержит таких символов, возвращается
‘unknown’. Если файл является изображением JPEG, PNG, GIF или WebP, возвращается
правильное расширение файла.
Требуется расширение PHP fileinfo
.
getSuggestedExtension(): ?string
Возвращает соответствующее расширение файла (без точки), соответствующее обнаруженному MIME-типу.
Требуется расширение PHP fileinfo
.
getUntrustedFullPath(): string
Возвращает исходный полный путь, указанный браузером во время загрузки каталога. Полный путь доступен только в PHP 8.1 и выше. В предыдущих версиях этот метод возвращает недоверенное имя файла.
Не доверяйте значению, возвращаемому этим методом. Клиент может отправить вредоносное имя файла с намерением испортить или взломать ваше приложение.
getSize(): int
Возвращает размер загруженного файла. Если загрузка не была
успешной, возвращается 0
.
getTemporaryFile(): string
Возвращает путь к временному местоположению загруженного файла.
Если загрузка не была успешной, возвращается ''
.
isImage(): bool
Возвращает true
, если загруженный файл является изображением
JPEG, PNG, GIF или WebP. Обнаружение основано на его сигнатуре. Целостность
всего файла не проверяется. Вы можете узнать, не повреждено ли
изображение, например, попытавшись загрузить его.
Требуется расширение PHP fileinfo
.
getImageSize(): ?array
Возвращает пару [width, height]
с размерами загруженного
изображения. Если загрузка не была успешной или это не действительное
изображение, возвращается null
.
toImage(): Nette\Utils\Image
Загружает изображение как объект Image.
Если загрузка не была успешной или изображение не является
действительным, выбрасывается исключение Nette\Utils\ImageException
.