Żą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.
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
.