HTTP request
Nette zapouzdřuje HTTP požadavek do objektů se srozumitelným API a zároveň poskytuje sanitizační filtr.
HTTP požadavek představuje objekt Nette\Http\Request.
Pokud pracujete s Nette, tento objekt je automaticky vytvořen frameworkem a můžete si jej nechat předat pomocí dependency injection. V presenterech stačí jen
zavolat metodu $this->getHttpRequest()
. Pokud pracujete mimo Nette Framework, můžete si vytvořit objekt pomocí
RequestFactory.
Velkou předností Nette je, že při vytváření objektu automaticky pročišťuje všechny vstupní parametry GET, POST, COOKIE a také URL od kontrolních znaků a neplatných UTF-8 sekvencí. S těmito daty pak můžete bezpečně dále pracovat. Očištěná data se následně používají v presenterech a formulářích.
Nette\Http\Request
Tento objekt je immutable (neměnný). Nemá žádné settery, má jen jeden tzv. wither withUrl()
, který objekt
nemění, ale vrací novou instanci se změněnou hodnotou.
withUrl (Nette\Http\UrlScript $url): Nette\Http\Request
Vrací klon s jinou URL.
getUrl(): Nette\Http\UrlScript
Vrací URL požadavku jako objekt UrlScript.
$url = $httpRequest->getUrl();
echo $url; // https://doc.nette.org/cs/?action=edit
echo $url->getHost(); // nette.org
Upozornění: prohlížeče neodesílají na server fragment, takže $url->getFragment()
bude vracet prázdný
řetězec.
getQuery (?string $key=null): string|array|null
Vrací parametry GET požadavku.
$all = $httpRequest->getQuery(); // vrací pole všech parametrů z URL
$id = $httpRequest->getQuery('id'); // vrací GET parametr 'id' (nebo null)
getPost (?string $key=null): string|array|null
Vrací parametry POST požadavku.
$all = $httpRequest->getPost(); // vrací pole všech parametrů z POST
$id = $httpRequest->getPost('id'); // vrací POST parametr 'id' (nebo null)
getFile (string|string[] $key): Nette\Http\FileUpload|array|null
Vrací upload jako objekt Nette\Http\FileUpload:
$file = $httpRequest->getFile('avatar');
if ($file->hasFile()) { // byl nějaký soubor nahraný?
$file->getUntrustedName(); // jméno souboru odeslané uživatelem
$file->getSanitizedName(); // jméno bez nebezpečných znaků
}
Pro přístup do zanořené struktury uveďte pole klíčů.
//<input type="file" name="my-form[details][avatar]" multiple>
$file = $request->getFile(['my-form', 'details', 'avatar']);
Protože nelze důvěřovat datům zvenčí a tedy ani spoléhat na podobu struktury souborů, je bezpečnější tento způsob
než třeba $request->getFiles()['my-form']['details']['avatar']
, který může selhat.
getFiles(): array
Vrátí strom všech uploadů v normalizované struktuře, jejíž listy jsou objekty Nette\Http\FileUpload:
$files = $httpRequest->getFiles();
getCookie (string $key): string|array|null
Vrací cookie nebo null
, když neexistuje.
$sessId = $httpRequest->getCookie('sess_id');
getCookies(): array
Vrací všechny cookies.
$cookies = $httpRequest->getCookies();
getMethod(): string
Vrací HTTP metodu, se kterou byl udělán požadavek.
$httpRequest->getMethod(); // GET, POST, HEAD, PUT
isMethod (string $method): bool
Testuje HTTP metodu, se kterou byl udělán požadavek. Parametr je case-insensitive.
if ($httpRequest->isMethod('GET')) // ...
getHeader (string $header): ?string
Vrací HTTP hlavičku nebo null
, pokud neexistuje. Parametr je case-insensitive.
$userAgent = $httpRequest->getHeader('User-Agent');
getHeaders(): array
Vrací všechny HTTP hlavičky jako asociativní pole.
$headers = $httpRequest->getHeaders();
echo $headers['Content-Type'];
isSecured(): bool
Je spojení šifrované (HTTPS)? Pro správnou funkčnost může být potřeba nastavit proxy.
isSameSite(): bool
Přichází požadavek ze stejné (sub)domény a je iniciován kliknutím na odkaz? Nette k detekci používá cookie
_nss
(dříve nette-samesite
).
isAjax(): bool
Jde o AJAXový požadavek?
getRemoteAddress(): ?string
Vrací IP adresu uživatele. Pro správnou funkčnost může být potřeba nastavit proxy.
getRemoteHost(): ?string
Vrací DNS překlad IP adresy uživatele. Pro správnou funkčnost může být potřeba nastavit proxy.
getBasicCredentials(): ?string
Vrací ověřovací údaje pro Basic HTTP authentication.
[$user, $password] = $httpRequest->getBasicCredentials();
getRawBody(): ?string
Vrací tělo HTTP požadavku.
$body = $httpRequest->getRawBody();
detectLanguage (array $langs): ?string
Detekuje jazyk. Jako parametr $lang
předáme pole s jazyky, které aplikace podporuje, a ona vrátí ten, který
by viděl návštěvníkův prohlížeč nejraději. Nejsou to žádná kouzla, jen se využívá hlavičky
Accept-Language
. Pokud nedojde k žádné shodě, vrací null
.
// prohlížeč odesílá např. Accept-Language: cs,en-us;q=0.8,en;q=0.5,sl;q=0.3
$langs = ['hu', 'pl', 'en']; // jazyky podporované aplikací
echo $httpRequest->detectLanguage($langs); // en
RequestFactory
Třída Nette\Http\RequestFactory slouží
k vytvoření instance Nette\Http\Request
, která reprezentuje aktuální HTTP požadavek. (Pokud pracujete
s Nette, objekt HTTP požadavku je automaticky vytvořen frameworkem.)
$factory = new Nette\Http\RequestFactory;
$httpRequest = $factory->fromGlobals();
Metoda fromGlobals()
vytvoří objekt požadavku na základě aktuálních globálních proměnných PHP
($_GET
, $_POST
, $_COOKIE
, $_FILES
a $_SERVER
). Při vytváření
objektu automaticky pročišťuje všechny vstupní parametry GET, POST, COOKIE a také URL od kontrolních znaků a neplatných
UTF-8 sekvencí, což zajišťuje bezpečnost při další práci s těmito daty.
RequestFactory lze před zavoláním fromGlobals()
konfigurovat:
- metodou
$factory->setBinary()
vypnete automatické čištění vstupních parametrů od kontrolních znaků a neplatných UTF-8 sekvencí. - metodou
$factory->setProxy(...)
uvedete IP adresu proxy serveru, což je nezbytné pro správnou detekci IP adresy uživatele.
RequestFactory umožňuje definovat filtry, které automaticky transformují části URL požadavku. Tyto filtry odstraňují nežádoucí znaky z URL, které tam mohou být vloženy například nesprávnou implementací komentářových systémů na různých webech:
// odstranění mezer z cesty
$requestFactory->urlFilters['path']['%20'] = '';
// odstranění tečky, čárky nebo pravé závorky z konce URI
$requestFactory->urlFilters['url']['[.,)]$'] = '';
// vyčištění cesty od zdvojených lomítek (výchozí filtr)
$requestFactory->urlFilters['path']['/{2,}'] = '/';
První klíč 'path'
nebo 'url'
určuje, na kterou část URL se filtr použije. Druhý klíč je
regulární výraz, který se má vyhledat, a hodnota je náhrada, která se použije místo nalezeného textu.
Uploadované soubory
Metoda Nette\Http\Request::getFiles()
vrací pole všech uploadů v normalizované struktuře, jejíž listy jsou
objekty Nette\Http\FileUpload. Ty zapouzdřují data
odeslaná formulářovým prvkem <input type=file>
.
Struktura reflektuje pojmenování prvků v HTML. V nejjednodušším případě to může být jediný pojmenovaný element formuláře odeslaný jako:
<input type="file" name="avatar">
V tomto případě $request->getFiles()
vrací pole:
[
'avatar' => /* FileUpload instance */
]
Objekt FileUpload
se vytvoří i v případě, že uživatel žádný soubor neodeslal nebo odeslání selhalo.
Jestli byl soubor odeslán vrací metoda hasFile()
:
$request->getFile('avatar')->hasFile();
V případě názvu elementu používajícího notaci pro pole:
<input type="file" name="my-form[details][avatar]">
vypadá vrácený strom takto:
[
'my-form' => [
'details' => [
'avatar' => /* FileUpload instance */
],
],
]
Lze vytvořit i pole souborů:
<input type="file" name="my-form[details][avatars][]" multiple>
V takovém případě vypadá struktura takto:
[
'my-form' => [
'details' => [
'avatars' => [
0 => /* FileUpload instance */,
1 => /* FileUpload instance */,
2 => /* FileUpload instance */,
],
],
],
]
Přistoupit k indexu 1 vnořeného pole lze nejlépe takto:
$file = $request->getFile(['my-form', 'details', 'avatars', 1]);
if ($file instanceof FileUpload) {
// ...
}
Protože nelze důvěřovat datům zvenčí a tedy ani spoléhat na podobu struktury souborů, je bezpečnější tento způsob
než třeba $request->getFiles()['my-form']['details']['avatars'][1]
, který může selhat.
Přehled metod FileUpload
hasFile(): bool
Vrací true
, pokud uživatel nějaký soubor uploadoval.
isOk(): bool
Vrací true
, pokud soubor byl nahrán úspěšně.
getError(): int
Vrací kód chyby při uploadu souboru. Jde o jednu z konstant UPLOAD_ERR_XXX. V případě, že upload proběhl
v pořádku, vrací UPLOAD_ERR_OK
.
move (string $dest)
Přesune nahraný soubor do nového umístění. Pokud cílový soubor již existuje, bude přepsán.
$file->move('/path/to/files/name.ext');
getContents(): ?string
Vrací obsah uploadovaného souboru. V případě, že upload nebyl úspěšný, vrací null
.
getContentType(): ?string
Detekuje MIME content type uploadovaného souboru na základě jeho signatury. V případě, že upload nebyl úspěšný nebo
detekce se nezdařila, vrací null
.
Vyžaduje PHP rozšíření fileinfo
.
getUntrustedName(): string
Vrací originální název souboru, jak jej odeslal prohlížeč.
Nevěřte hodnotě vrácené touto metodou. Klient mohl odeslat škodlivý název souboru s úmyslem poškodit nebo hacknout vaši aplikaci.
getSanitizedName(): string
Vrací sanitizovaný název souboru. Obsahuje pouze ASCII znaky [a-zA-Z0-9.-]
. Pokud název takové znaky
neobsahuje, vrátí 'unknown'
. Pokud je soubor obrázek ve formátu JPEG, PNG, GIF, WebP nebo AVIF, vrátí
i správnou příponu.
Vyžaduje PHP rozšíření fileinfo
.
getSuggestedExtension(): ?string
Vrací vhodnou příponu souboru (bez tečky) odpovídající zjištěnému MIME typu.
Vyžaduje PHP rozšíření fileinfo
.
getUntrustedFullPath(): string
Vrací originální cestu k souboru, jak ji odeslal prohlížeč při uploadu složky. Celá cesta je dostupná pouze v PHP 8.1 a vyšším. V předchozích verzích tato metoda vrací originální název souboru.
Nevěřte hodnotě vrácené touto metodou. Klient mohl odeslat škodlivý název souboru s úmyslem poškodit nebo hacknout vaši aplikaci.
getSize(): int
Vrací velikost uploadovaného souboru. V případě, že upload nebyl úspěšný, vrací 0
.
getTemporaryFile(): string
Vrací cestu k dočasné lokaci uploadovaného souboru. V případě, že upload nebyl úspěšný, vrací
''
.
isImage(): bool
Vrací true
, pokud nahraný soubor je obrázek ve formátu JPEG, PNG, GIF, WebP nebo AVIF. Detekce probíhá na
základě jeho signatury a neověřuje se integrita celého souboru. Zda není obrázek poškozený lze zjistit například
pokusem o jeho načtení.
Vyžaduje PHP rozšíření fileinfo
.
getImageSize(): ?array
Vrací dvojici [šířka, výška]
s rozměry uploadovaného obrázku. V případě, že upload nebyl
úspěšný nebo nejde o platný obrázek, vrací null
.
toImage(): Nette\Utils\Image
Načte obrázek jak objekt Image. V případě, že upload nebyl
úspěšný nebo nejde o platný obrázek, vyhodí výjimku Nette\Utils\ImageException
.