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
.