Żądanie HTTP

Nette enkapsuluje żądanie HTTP w obiekty z zrozumiałym API i jednocześnie zapewnia filtr sanityzujący.

Żądanie HTTP reprezentuje obiekt Nette\Http\Request. Jeśli pracujesz z Nette, ten obiekt jest automatycznie tworzony przez framework i możesz go otrzymać za pomocą wstrzykiwania zależności. W prezenterach wystarczy tylko wywołać metodę $this->getHttpRequest(). Jeśli pracujesz poza Nette Framework, możesz utworzyć obiekt za pomocą RequestFactory.

Dużą zaletą Nette jest to, że podczas tworzenia obiektu automatycznie oczyszcza wszystkie parametry wejściowe GET, POST, COOKIE oraz URL z znaków kontrolnych i nieprawidłowych sekwencji UTF-8. Z tymi danymi możesz następnie bezpiecznie dalej pracować. Oczyszczone dane są następnie używane w prezenterach i formularzach.

Instalacja i wymagania

Nette\Http\Request

Ten obiekt jest immutable (niezmienny). Nie ma żadnych setterów, ma tylko jeden tzw. wither withUrl(), który nie zmienia obiektu, ale zwraca nową instancję ze zmienioną wartością.

withUrl (Nette\Http\UrlScript $url): Nette\Http\Request

Zwraca klona z innym adresem URL.

getUrl(): Nette\Http\UrlScript

Zwraca adres URL żądania jako obiekt UrlScript.

$url = $httpRequest->getUrl();
echo $url; // https://doc.nette.org/cs/?action=edit
echo $url->getHost(); // nette.org

Uwaga: przeglądarki nie wysyłają fragmentu na serwer, więc $url->getFragment() będzie zwracać pusty ciąg znaków.

getQuery (?string $key=null): string|array|null

Zwraca parametry żądania GET.

$all = $httpRequest->getQuery(); // zwraca tablicę wszystkich parametrów z adresu URL
$id = $httpRequest->getQuery('id'); // zwraca parametr GET 'id' (lub null)

getPost (?string $key=null): string|array|null

Zwraca parametry żądania POST.

$all = $httpRequest->getPost(); // zwraca tablicę wszystkich parametrów z POST
$id = $httpRequest->getPost('id'); // zwraca parametr POST 'id' (lub null)

getFile (string|string[] $key): Nette\Http\FileUpload|array|null

Zwraca przesłany plik jako obiekt Nette\Http\FileUpload:

$file = $httpRequest->getFile('avatar');
if ($file?->hasFile()) { // czy jakiś plik został przesłany?
	$file->getUntrustedName(); // nazwa pliku wysłana przez użytkownika
	$file->getSanitizedName(); // nazwa bez niebezpiecznych znaków
}

Aby uzyskać dostęp do zagnieżdżonej struktury, podaj tablicę kluczy.

//<input type="file" name="my-form[details][avatar]" multiple>
$file = $request->getFile(['my-form', 'details', 'avatar']);

Ponieważ nie można ufać danym z zewnątrz, a zatem polegać na strukturze plików, ten sposób jest bezpieczniejszy niż na przykład $request->getFiles()['my-form']['details']['avatar'], który może zawieść.

getFiles(): array

Zwraca drzewo wszystkich przesłanych plików w znormalizowanej strukturze, której liśćmi są obiekty Nette\Http\FileUpload:

$files = $httpRequest->getFiles();

getCookie (string $key): string|array|null

Zwraca ciasteczko lub null, jeśli nie istnieje.

$sessId = $httpRequest->getCookie('sess_id');

getCookies(): array

Zwraca wszystkie ciasteczka.

$cookies = $httpRequest->getCookies();

getMethod(): string

Zwraca metodę HTTP, za pomocą której zostało wykonane żądanie.

$httpRequest->getMethod(); // GET, POST, HEAD, PUT

isMethod (string $method)bool

Testuje metodę HTTP, za pomocą której zostało wykonane żądanie. Parametr jest niewrażliwy na wielkość liter.

if ($httpRequest->isMethod('GET')) // ...

getHeader (string $header): ?string

Zwraca nagłówek HTTP lub null, jeśli nie istnieje. Parametr jest niewrażliwy na wielkość liter.

$userAgent = $httpRequest->getHeader('User-Agent');

getHeaders(): array

Zwraca wszystkie nagłówki HTTP jako tablicę asocjacyjną.

$headers = $httpRequest->getHeaders();
echo $headers['Content-Type'];

isSecured(): bool

Czy połączenie jest szyfrowane (HTTPS)? Aby zapewnić prawidłowe działanie, może być konieczne skonfigurowanie proxy.

isSameSite(): bool

Czy żądanie pochodzi z tej samej (sub)domeny i jest inicjowane przez kliknięcie linku? Nette używa ciasteczka _nss (wcześniej nette-samesite) do detekcji.

isAjax(): bool

Czy to jest żądanie AJAX?

getRemoteAddress(): ?string

Zwraca adres IP użytkownika. Aby zapewnić prawidłowe działanie, może być konieczne skonfigurowanie proxy.

getRemoteHost(): ?string

Zwraca tłumaczenie DNS adresu IP użytkownika. Aby zapewnić prawidłowe działanie, może być konieczne skonfigurowanie proxy.

getBasicCredentials(): ?array

Zwraca dane uwierzytelniające dla Basic HTTP authentication.

[$user, $password] = $httpRequest->getBasicCredentials();

getRawBody(): ?string

Zwraca ciało żądania HTTP.

$body = $httpRequest->getRawBody();

detectLanguage (array $langs): ?string

Wykrywa język. Jako parametr $lang przekazujemy tablicę z językami obsługiwanymi przez aplikację, a ona zwraca ten, który przeglądarka odwiedzającego preferuje najbardziej. To nie są żadne czary, po prostu wykorzystuje nagłówek Accept-Language. Jeśli nie ma dopasowania, zwraca null.

// przeglądarka wysyła np. Accept-Language: cs,en-us;q=0.8,en;q=0.5,sl;q=0.3

$langs = ['hu', 'pl', 'en']; // języki obsługiwane przez aplikację
echo $httpRequest->detectLanguage($langs); // en

RequestFactory

Klasa Nette\Http\RequestFactory służy do tworzenia instancji Nette\Http\Request, która reprezentuje bieżące żądanie HTTP. (Jeśli pracujesz z Nette, obiekt żądania HTTP jest automatycznie tworzony przez framework.)

$factory = new Nette\Http\RequestFactory;
$httpRequest = $factory->fromGlobals();

Metoda fromGlobals() tworzy obiekt żądania na podstawie bieżących globalnych zmiennych PHP ($_GET, $_POST, $_COOKIE, $_FILES i $_SERVER). Podczas tworzenia obiektu automatycznie oczyszcza wszystkie parametry wejściowe GET, POST, COOKIE oraz URL z znaków kontrolnych i nieprawidłowych sekwencji UTF-8, co zapewnia bezpieczeństwo podczas dalszej pracy z tymi danymi.

RequestFactory można skonfigurować przed wywołaniem fromGlobals():

  • metodą $factory->setBinary() wyłączysz automatyczne czyszczenie parametrów wejściowych z znaków kontrolnych i nieprawidłowych sekwencji UTF-8.
  • metodą $factory->setProxy(...) podasz adres IP serwera proxy, co jest niezbędne do poprawnego wykrywania adresu IP użytkownika.

RequestFactory umożliwia definiowanie filtrów, które automatycznie transformują części adresu URL żądania. Filtry te usuwają niepożądane znaki z adresu URL, które mogą się tam znaleźć na przykład z powodu nieprawidłowej implementacji systemów komentarzy na różnych stronach:

// usunięcie spacji ze ścieżki
$requestFactory->urlFilters['path']['%20'] = '';

// usunięcie kropki, przecinka lub prawego nawiasu z końca URI
$requestFactory->urlFilters['url']['[.,)]$'] = '';

// oczyszczenie ścieżki z podwójnych ukośników (filtr domyślny)
$requestFactory->urlFilters['path']['/{2,}'] = '/';

Pierwszy klucz 'path' lub 'url' określa, do której części adresu URL filtr zostanie zastosowany. Drugi klucz to wyrażenie regularne, które ma zostać wyszukane, a wartość to zamiennik, który zostanie użyty zamiast znalezionego tekstu.

Przesłane pliki

Metoda Nette\Http\Request::getFiles() zwraca tablicę wszystkich przesłanych plików w znormalizowanej strukturze, której liśćmi są obiekty Nette\Http\FileUpload. Enkapsulują one dane wysłane przez element formularza <input type=file>.

Struktura odzwierciedla nazewnictwo elementów w HTML. W najprostszym przypadku może to być pojedynczy nazwany element formularza wysłany jako:

<input type="file" name="avatar">

W tym przypadku $request->getFiles() zwraca tablicę:

[
	'avatar' => /* Instancja FileUpload */
]

Obiekt FileUpload jest tworzony nawet wtedy, gdy użytkownik nie wysłał żadnego pliku lub wysyłanie nie powiodło się. Czy plik został wysłany, zwraca metoda hasFile():

$request->getFile('avatar')?->hasFile();

W przypadku nazwy elementu używającej notacji dla tablic:

<input type="file" name="my-form[details][avatar]">

zwrócone drzewo wygląda tak:

[
	'my-form' => [
		'details' => [
			'avatar' => /* Instancja FileUpload */
		],
	],
]

Można również utworzyć tablicę plików:

<input type="file" name="my-form[details][avatars][]" multiple>

W takim przypadku struktura wygląda tak:

[
	'my-form' => [
		'details' => [
			'avatars' => [
				0 => /* Instancja FileUpload */,
				1 => /* Instancja FileUpload */,
				2 => /* Instancja FileUpload */,
			],
		],
	],
]

Dostęp do indeksu 1 zagnieżdżonej tablicy najlepiej uzyskać w ten sposób:

$file = $request->getFile(['my-form', 'details', 'avatars', 1]);
if ($file instanceof FileUpload) {
	// ...
}

Ponieważ nie można ufać danym z zewnątrz, a zatem polegać na strukturze plików, ten sposób jest bezpieczniejszy niż na przykład $request->getFiles()['my-form']['details']['avatars'][1], który może zawieść.

Przegląd metod FileUpload

hasFile(): bool

Zwraca true, jeśli użytkownik przesłał jakiś plik.

isOk(): bool

Zwraca true, jeśli plik został pomyślnie przesłany.

getError(): int

Zwraca kod błędu podczas przesyłania pliku. Jest to jedna ze stałych UPLOAD_ERR_XXX. Jeśli przesyłanie przebiegło pomyślnie, zwraca UPLOAD_ERR_OK.

move (string $dest)

Przenosi przesłany plik do nowej lokalizacji. Jeśli plik docelowy już istnieje, zostanie nadpisany.

$file->move('/path/to/files/name.ext');

getContents(): ?string

Zwraca zawartość przesłanego pliku. Jeśli przesyłanie nie powiodło się, zwraca null.

getContentType(): ?string

Wykrywa typ zawartości MIME przesłanego pliku na podstawie jego sygnatury. Jeśli przesyłanie nie powiodło się lub wykrywanie nie powiodło się, zwraca null.

Wymaga rozszerzenia PHP fileinfo.

getUntrustedName(): string

Zwraca oryginalną nazwę pliku wysłaną przez przeglądarkę.

Nie ufaj wartości zwracanej przez tę metodę. Klient mógł wysłać złośliwą nazwę pliku w celu uszkodzenia lub zhakowania aplikacji.

getSanitizedName(): string

Zwraca oczyszczoną nazwę pliku. Zawiera tylko znaki ASCII [a-zA-Z0-9.-]. Jeśli nazwa nie zawiera takich znaków, zwraca 'unknown'. Jeśli plik jest obrazem w formacie JPEG, PNG, GIF, WebP lub AVIF, zwraca również poprawne rozszerzenie.

Wymaga rozszerzenia PHP fileinfo.

getSuggestedExtension(): ?string

Zwraca odpowiednie rozszerzenie pliku (bez kropki) odpowiadające wykrytemu typowi MIME.

Wymaga rozszerzenia PHP fileinfo.

getUntrustedFullPath(): string

Zwraca oryginalną ścieżkę do pliku, tak jak została wysłana przez przeglądarkę podczas przesyłania folderu. Pełna ścieżka jest dostępna tylko w PHP 8.1 i nowszych. W poprzednich wersjach ta metoda zwraca oryginalną nazwę pliku.

Nie ufaj wartości zwracanej przez tę metodę. Klient mógł wysłać złośliwą nazwę pliku w celu uszkodzenia lub zhakowania aplikacji.

getSize(): int

Zwraca rozmiar przesłanego pliku. Jeśli przesyłanie nie powiodło się, zwraca 0.

getTemporaryFile(): string

Zwraca ścieżkę do tymczasowej lokalizacji przesłanego pliku. Jeśli przesyłanie nie powiodło się, zwraca ''.

isImage(): bool

Zwraca true, jeśli przesłany plik jest obrazem w formacie JPEG, PNG, GIF, WebP lub AVIF. Wykrywanie odbywa się na podstawie jego sygnatury i nie weryfikuje integralności całego pliku. Czy obraz nie jest uszkodzony, można sprawdzić na przykład próbując go załadować.

Wymaga rozszerzenia PHP fileinfo.

getImageSize(): ?array

Zwraca parę [szerokość, wysokość] z wymiarami przesłanego obrazu. Jeśli przesyłanie nie powiodło się lub nie jest to prawidłowy obraz, zwraca null.

toImage(): Nette\Utils\Image

Ładuje obraz jako obiekt Image. Jeśli przesyłanie nie powiodło się lub nie jest to prawidłowy obraz, zgłasza wyjątek Nette\Utils\ImageException.

wersja: 4.0