HTTP заявка
Nette капсулира HTTP заявката в обекти с разбираем API и същевременно предоставя саниращ филтър.
HTTP заявката представлява обект Nette\Http\Request. Ако работите с Nette,
този обект се създава автоматично от framework-а и можете да го получите
чрез dependency injection. В
презентерите е достатъчно само да извикате метода
$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
Връща бисквитка или null
, когато не съществува.
$sessId = $httpRequest->getCookie('sess_id');
getCookies(): array
Връща всички бисквитки.
$cookies = $httpRequest->getCookies();
getMethod(): string
Връща HTTP метода, с който е направена заявката.
$httpRequest->getMethod(); // GET, POST, HEAD, PUT
isMethod (string $method): bool
Тества HTTP метода, с който е направена заявката. Параметърът е case-insensitive.
if ($httpRequest->isMethod('GET')) // ...
getHeader (string $header): ?string
Връща HTTP хедър или null
, ако не съществува. Параметърът е
case-insensitive.
$userAgent = $httpRequest->getHeader('User-Agent');
getHeaders(): array
Връща всички HTTP хедъри като асоциативен масив.
$headers = $httpRequest->getHeaders();
echo $headers['Content-Type'];
isSecured(): bool
Връзката шифрована ли е (HTTPS)? За правилната функционалност може да е необходимо да се настрои прокси.
isSameSite(): bool
Заявката идва ли от същия (под)домейн и е инициирана чрез кликване
върху връзка? Nette използва бисквитката _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
Открива езика. Като параметър $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
Класът Nette\Http\RequestFactory
служи за създаване на екземпляр на Nette\Http\Request
, който
представлява текущата HTTP заявка. (Ако работите с Nette, обектът на HTTP
заявката се създава автоматично от framework-а.)
$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
.