Żądanie HTTP
Nette enkapsuluje żądanie HTTP w obiekty o zrozumiałym API, zapewniając jednocześnie filtr sanityzujący.
Żądanie HTTP jest reprezentowane przez obiekt Nette\Http\Request, do którego uzyskujesz dostęp poprzez
przekazanie go za pomocą zastrzyku zależności. W presenterech
wystarczy zadzwonić na $httpRequest = $this->getHttpRequest()
.
Co ważne, gdy Nette tworzy ten obiekt, sanityzuje wszystkie parametry wejściowe GET, POST, COOKIE, a także URL ze znaków sterujących i nieprawidłowych sekwencji UTF-8. Można więc wtedy bezpiecznie kontynuować pracę z danymi. Oczyszczone dane są następnie wykorzystywane w prezenterach i formularzach.
Nette\NRequest
Ten obiekt jest niezmienny. Nie posiada żadnych seterów, ma tylko jeden tzw. wither withUrl()
, który nie
modyfikuje obiektu, ale zwraca nową instancję ze zmienioną wartością.
withUrl(Nette\Http\UrlScript $url): Nette\Http\Request
Zwraca klon z innym adresem URL.
getUrl(): Nette\Http\UrlScript
Zwraca adres URL żądania jako obiekt UrlScript.
$url = $httpRequest->getUrl();
echo $url; // https://doc.nette.org/en/?action=edit
echo $url->getHost(); // nette.org
Ostrzeżenie: Przeglądarki nie wysyłają fragmentu do serwera, więc $url->getFragment()
zwróci 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 POSTa
$id = $httpRequest->getPost('id'); // zwraca parametr POST 'id' (lub null)
getFile(string|string[] $key): Nette\Http\FileUpload|array|null
Zwraca przesłanie jako obiekt Nette\Http\FileUpload:
$file = $httpRequest->getFile('avatar');
if ($file->hasFile()) { // czy jakiś plik został przesłany?
$file->getUntrustedName(); // nazwa pliku przesłanego przez użytkownika
$file->getSanitizedName(); // nazwa bez niebezpiecznych znaków
}
Określenie pola kluczowego dla dostępu do struktury zagnieżdżonej.
//<input type="file" name="my-form[details][avatar]" multiple>
$file = $request->getFile(['my-form', 'details', 'avatar']);
Ponieważ nie można ufać zewnętrznym danym, a zatem nie można polegać na formie struktury plików, jest to bezpieczniejsza
metoda niż np. $request->getFiles()['my-form']['details']['avatar']
co może się nie udać.
getFiles(): array
Zwraca drzewo wszystkich uploadów w znormalizowanej strukturze, której liście są obiektami Nette\Http\FileUpload:
$files = $httpRequest->getFiles();
getCookie(string $key): string|array|null
Zwraca cookie 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. Wielkość liter w parametrze nie ma znaczenia.
if ($httpRequest->isMethod('GET')) // ...
getHeader(string $header): ?string
Zwraca nagłówek HTTP lub null
, jeśli nie istnieje. Wielkość liter w parametrze nie ma znaczenia.
$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)? Może być konieczne skonfigurowanie proxy dla prawidłowej funkcjonalności.
isSameSite(): bool
Czy żądanie pochodzi z tej samej (pod)domeny i jest inicjowane przez kliknięcie na link? Nette używa pliku cookie
_nss
(dawniej nette-samesite
), aby to wykryć.
isAjax(): bool
Czy to jest żądanie AJAX?
getRemoteAddress(): ?string
Zwraca adres IP użytkownika. Może być konieczne skonfigurowanie proxy dla prawidłowej funkcjonalności.
getRemoteHost(): ?string
Zwraca rozdzielczość DNS adresu IP użytkownika. Może być konieczne skonfigurowanie proxy dla prawidłowej funkcjonalności.
getBasicCredentials(): ?string
Zwraca dane uwierzytelniające dla uwierzytelniania Basic HTTP.
[$user, $password] = $httpRequest->getBasicCredentials();
getRawBody(): ?string
Zwraca treść żądania HTTP.
$body = $httpRequest->getRawBody();
detectLanguage(array $langs): ?string
Wykrywa język. Przekaż tablicę języków obsługiwanych przez aplikację jako parametr $lang
, a zwróci ona
ten, który przeglądarka odwiedzającego wolałaby zobaczyć. Nie ma w tym żadnej magii, po prostu używa nagłówka
Accept-Language
. Jeśli nie ma dopasowania, zwraca null
.
// przeglądarka wysyła np. Accept-Language: en-us;q=0.8,en;q=0.5,en;q=0.3
$langs = ['hu', 'pl', 'en']; // języki obsługiwane przez aplikację
echo $httpRequest->detectLanguage($langs); // pl
RequestFactory
Bieżący obiekt żądania HTTP wytworzy Nette\Http\RequestFactory. Jeśli piszesz aplikację, która nie używa kontenera DI, wytworzysz żądanie w następujący sposób:
$factory = new Nette\Http\RequestFactory;
$httpRequest = $factory->fromGlobals();
RequestFactory może być skonfigurowany przed wywołaniem fromGlobals()
. Możemy wyłączyć sanityzację
parametrów wejściowych ze znaków sterujących i nieprawidłowych sekwencji UTF-8 za pomocą
$factory->setBinary()
. A także skonfigurować serwer proxy za pomocą $factory->setProxy(...)
,
co jest ważne dla prawidłowego wykrywania adresu IP użytkownika.
Za pomocą tzw. filtrów można oczyścić adres URL ze znaków, które mogą się do niego dostać, np. z powodu źle wdrożonych systemów komentarzy na różnych zagranicznych stronach:
// usuń spacje z drogi
$requestFactory->urlFilters['path']['%20'] = '';
// usuń kropkę, przecinek lub prawy nawias z końca URI
$requestFactory->urlFilters['url']['[.,)]$'] = '';
// czyszczenie ścieżki z podwójnych ukośników (domyślny filtr)
$requestFactory->urlFilters['path']['/{2,}'] = '/';
Przesłane pliki
Metoda Nette\Http\Request::getFiles()
zwraca tablicę wszystkich uploadów w znormalizowanej strukturze, której
listki są obiektami Nette\Http\FileUpload. Zawierają one
dane przesł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 złożony jako:
<input type="file" name="avatar">
W tym przypadku $request->getFiles()
zwraca tablicę:
[
'avatar' => /* FileUpload instance */
]
Obiekt FileUpload
jest tworzony nawet jeśli użytkownik nie przesłał żadnego pliku lub przesłanie nie
powiodło się. Jeśli plik został załadowany, to zwraca się metoda hasFile()
:
$request->getFile('avatar')->hasFile();
W przypadku nazwy elementu z wykorzystaniem notacji tablicowej:
<input type="file" name="my-form[details][avatar]">
zwrócone drzewo wygląda tak:
[
'my-form' => [
'details' => [
'avatar' => /* FileUpload instance */
],
],
]
Można również utworzyć tablicę plików:
<input type="file" name="my-form[details][avatars][]" multiple>
W tym przypadku struktura wygląda tak:
[
'my-form' => [
'details' => [
'avatars' => [
0 => /* FileUpload instance */,
1 => /* FileUpload instance */,
2 => /* FileUpload instance */,
],
],
],
]
Najlepszym sposobem podejścia do indeksu 1 zagnieżdżonej tablicy jest następujący sposób:
$file = $request->getFile(['my-form', 'details', 'avatars', 1]);
if ($file instanceof FileUpload) {
// ...
}
Ponieważ nie można ufać zewnętrznym danym, a zatem nie można polegać na formie struktury plików, jest to bezpieczniejszy
sposób niż np. $request->getFiles()['my-form']['details']['avatars'][1]
co może się nie udać.
Przegląd metod FileUpload
hasFile(): bool
Zwraca true
, jeśli użytkownik przesłał plik.
isOk(): bool
Zwraca true
, jeśli plik został przesłany pomyślnie.
getError(): int
Zwraca kod błędu podczas przesyłania pliku. Jest to jedna ze stałych UPLOAD_ERR_XXX. Jeśli przesyłanie zakończyło się
sukcesem, zwraca UPLOAD_ERR_OK
.
move(string $dest)
Przenosi przesłany plik do nowej lokalizacji. Jeśli plik docelowy już istnieje, zostanie on nadpisany.
$file->move('/path/to/files/name.ext');
getContents(): ?string
Zwraca zawartość przesłanego pliku. Jeśli przesłanie nie powiodło się, zwraca null
.
getContentType(): ?string
Wykrywa typ zawartości MIME przesłanego pliku na podstawie jego sygnatury. Jeśli przesłanie nie powiodło się lub wykrycie
nie powiodło się, zwraca null
.
Wymaga rozszerzenia PHP fileinfo
.
getUntrustedName(): string
Zwraca oryginalną nazwę pliku przesłaną przez przeglądarkę.
Nie należy ufać wartości zwracanej przez tę metodę. Klient mógł wysłać złośliwą nazwę pliku z zamiarem uszkodzenia lub zhakowania Twojej 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 JPEG, PNG, GIF lub WebP, zwraca również prawidłowe
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ę pliku, jak wysłane przez przeglądarkę, gdy folder został załadowany. Pełna ścieżka jest dostępna tylko w PHP 8.1 i wyższych. W poprzednich wersjach metoda ta zwracała oryginalną nazwę pliku.
Nie należy ufać wartości zwracanej przez tę metodę. Klient mógł wysłać złośliwą nazwę pliku z zamiarem uszkodzenia lub zhakowania Twojej aplikacji.
getSize(): int
Zwraca rozmiar przesłanego pliku. Zwraca 0
jeśli załadowanie nie powiodło się.
getTemporaryFile(): string
Zwraca ścieżkę do tymczasowej lokalizacji przesłanego pliku. Jeśli przesłanie nie powiodło się, zwraca
''
.
isImage(): bool
Zwraca true
, jeśli przesłany plik jest obrazem JPEG, PNG, GIF lub WebP. Wykrywanie oparte jest na jego
sygnaturze i nie sprawdza integralności całego pliku. Możliwe jest określenie, czy obraz jest uszkodzony, na przykład
próbując go załadować.
Wymaga rozszerzenia PHP fileinfo
.
getImageSize(): ?array
Zwraca parę [šířka, výška]
z wymiarami przesłanego obrazu. Jeśli przesłanie nie powiodło się lub nie
jest to prawidłowy obraz, zwraca null
.
toImage(): Nette\Utils\Image
Wczytuje obraz jako obiekt Image. Jeśli przesłanie nie powiodło się lub nie
jest prawidłowym obrazem, rzuca wyjątek Nette\Utils\ImageException
.