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/uk/?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
Повертає всі cookies.
$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: uk,en-us;q=0.8,en;q=0.5,sl;q=0.3 $langs = ['hu', 'pl', 'uk']; // мови, підтримувані програмою echo $httpRequest->detectLanguage($langs); // uk 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)
Переміщує завантажений файл у нове місце. Якщо цільовий файл вже існує, він буде перезаписаний.
$file->move('/path/to/files/name.ext'); getContents(): ?string
Повертає вміст завантаженого файлу. У випадку, якщо завантаження не було успішним, повертає null.
getContentType(): ?string
Визначає MIME content type завантаженого файлу на основі його сигнатури. У випадку, якщо завантаження не було успішним або визначення не вдалося, повертає null.
Вимагає PHP-розширення fileinfo.
getUntrustedName(): string
Повертає оригінальну назву файлу, як її надіслав браузер.
Не довіряйте значенню, повернутому цим методом. Клієнт міг надіслати шкідливу назву файлу з наміром пошкодити або зламати вашу програму.
getSanitizedName(): string
Повертає санітизовану назву файлу. Містить лише 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.