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.

Instalace a požadavky

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.

verze: 4.0 3.x 2.x