Nette Documentation Preview

syntax
Richiesta HTTP
**************

.[perex]
Nette incapsula la richiesta HTTP in oggetti con un'API chiara e offre allo stesso tempo un filtro di sanificazione.

La richiesta HTTP è rappresentata dall'oggetto [api:Nette\Http\Request]. Se lavorate con Nette, questo oggetto viene creato automaticamente dal framework e potete farvelo passare con la [dependency injection |dependency-injection:passing-dependencies]. Nei presenter basta chiamare il metodo `$this->getHttpRequest()`. Se lavorate fuori dal Nette Framework, potete creare l'oggetto con [#RequestFactory].

Un grande vantaggio di Nette è che, quando crea l'oggetto, sanifica automaticamente tutti i parametri in ingresso (GET, POST, COOKIE) e anche l'URL, rimuovendo i caratteri di controllo e le sequenze UTF-8 non valide. Con questi dati potete poi lavorare in sicurezza. I dati sanificati vengono usati in seguito nei presenter e nei form.

→ [Installazione e requisiti |@home#Installazione]


Nette\Http\Request
==================

Questo oggetto è immutabile. Non ha setter, ha un solo cosiddetto wither, `withUrl()`, che non modifica l'oggetto ma restituisce una nuova istanza con il valore modificato.


withUrl(Nette\Http\UrlScript $url): Nette\Http\Request .[method]
----------------------------------------------------------------
Restituisce un clone con un URL diverso.


getUrl(): Nette\Http\UrlScript .[method]
----------------------------------------
Restituisce l'URL della richiesta come oggetto [UrlScript |urls#UrlScript].

```php
$url = $httpRequest->getUrl();
echo $url; // https://nette.org/en/documentation?action=edit
echo $url->getHost(); // nette.org
```

Attenzione: i browser non inviano il frammento al server, quindi `$url->getFragment()` restituirà una stringa vuota.


getQuery(?string $key=null): string|array|null .[method]
--------------------------------------------------------
Restituisce i parametri della richiesta GET.

```php
$all = $httpRequest->getQuery();    // array di tutti i parametri dell'URL
$id = $httpRequest->getQuery('id'); // restituisce il parametro GET 'id' (oppure null)
```


getPost(?string $key=null): string|array|null .[method]
-------------------------------------------------------
Restituisce i parametri della richiesta POST.

```php
$all = $httpRequest->getPost();     // array di tutti i parametri POST
$id = $httpRequest->getPost('id');  // restituisce il parametro POST 'id' (oppure null)
```


getFile(string|string[] $key): ?Nette\Http\FileUpload .[method]
---------------------------------------------------------------
Restituisce un [upload |#File caricati] come oggetto [api:Nette\Http\FileUpload]:

```php
$file = $httpRequest->getFile('avatar');
if ($file?->hasFile()) { // è stato caricato qualche file?
	$file->getUntrustedName(); // nome del file inviato dall'utente
	$file->getSanitizedName(); // nome senza caratteri pericolosi
}
```

Per accedere a una struttura annidata indicate un array di chiavi.

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

Poiché non potete fidarvi dei dati esterni e quindi contare sulla struttura dei file, questo approccio è più sicuro di per esempio `$request->getFiles()['my-form']['details']['avatar']`, che potrebbe fallire.


getFiles(): array .[method]
---------------------------
Restituisce un albero di [tutti gli upload |#File caricati] in una struttura normalizzata, le cui foglie sono oggetti [api:Nette\Http\FileUpload]:

```php
$files = $httpRequest->getFiles();
```


getCookie(string $key): ?string .[method]
-----------------------------------------
Restituisce un cookie oppure `null` se non esiste.

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


getCookies(): array .[method]
-----------------------------
Restituisce tutti i cookie.

```php
$cookies = $httpRequest->getCookies();
```


getMethod(): string .[method]
-----------------------------
Restituisce il metodo HTTP con cui è stata fatta la richiesta.

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


isMethod(string $method): bool .[method]
----------------------------------------
Verifica il metodo HTTP con cui è stata fatta la richiesta. Il parametro non fa distinzione tra maiuscole e minuscole.

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


getHeader(string $header): ?string .[method]
--------------------------------------------
Restituisce un header HTTP oppure `null` se non esiste. Il parametro non fa distinzione tra maiuscole e minuscole.

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


getHeaders(): array<string, string> .[method]
---------------------------------------------
Restituisce tutti gli header HTTP come array associativo. Le chiavi sono normalizzate in minuscolo.

```php
$headers = $httpRequest->getHeaders();
echo $headers['content-type'];
```


isSecured(): bool .[method]
---------------------------
La connessione è cifrata (HTTPS)? Perché funzioni correttamente può servire [impostare il proxy |configuration#Proxy HTTP].


isSameSite(): bool .[method deprecated]
---------------------------------------
La richiesta proviene dallo stesso sito? Dalla versione 3.4 è sostituito dal più capace [isFrom() |#isFrom()].


isFrom(FetchSite|array $site, FetchDest|array|null $dest=null, ?bool $user=null): bool .[method]{data-version:3.4.0}
--------------------------------------------------------------------------------------------------------------------
Vi dice da dove è arrivata la richiesta e in che modo il browser l'ha fatta, in base agli header `Sec-Fetch-*` (i cosiddetti [Fetch Metadata |https://developer.mozilla.org/en-US/docs/Glossary/Fetch_metadata_request_header]) che il browser imposta da sé e che una pagina in esecuzione nel browser della vittima non può né falsificare né rimuovere. Nette lo usa internamente per proteggere automaticamente form e segnali dal [Cross-Site Request Forgery |nette:glossary#Cross-Site Request Forgery (CSRF)] (CSRF). Torna utile quando volete proteggere vostre azioni sensibili, per esempio endpoint di API o link distruttivi.

Il metodo restituisce `true` solo quando la richiesta soddisfa **tutte** le condizioni che indicate. Il primo parametro `$site` descrive la relazione tra la pagina che ha originato la richiesta e il vostro sito (l'header `Sec-Fetch-Site`). Accetta un singolo valore o un elenco di questi casi di `FetchSite`:

- `FetchSite::SameOrigin` - dalla stessa identica origine (schema, host e porta)
- `FetchSite::SameSite` - dallo stesso sito, eventualmente da un sottodominio diverso
- `FetchSite::CrossSite` - da un sito estraneo
- `FetchSite::None` - l'ha originata direttamente l'utente, per esempio digitando l'URL o aprendo un segnalibro

```php
// la richiesta proviene dalle nostre pagine?
if (!$httpRequest->isFrom([FetchSite::SameOrigin, FetchSite::SameSite])) {
	// blocchiamo l'azione
}
```

Il parametro opzionale `$dest` (l'header `Sec-Fetch-Dest`) dice che tipo di risorsa il browser sta scaricando, per esempio `FetchDest::Document` per una navigazione di primo livello oppure `FetchDest::Empty` per una richiesta fatta da JavaScript. Il parametro opzionale `$user` (l'header `Sec-Fetch-User`) indica se la navigazione è stata provocata da una vera azione dell'utente, come cliccare un link o inviare un form; passate `true` per richiederlo.

Un controllo che un'azione sia raggiungibile solo dalle vostre pagine e solo tramite una vera azione dell'utente appare allora così:

```php
if (!$httpRequest->isFrom(FetchSite::SameOrigin, FetchDest::Document, user: true)) {
	$this->error();
}
```

.[note]
I browser più vecchi (Safari prima della 16.4) non inviano gli header `Sec-Fetch-*`. Per essi Nette ripiega su un cookie `SameSite=Strict` che prova solo che la richiesta non è cross-site. Un controllo che richieda anche `$dest` o `$user` non si può verificare in questo modo e in quei browser restituisce `false`: se è troppo severo, verificate solo `$site`.


isAjax(): bool .[method]
------------------------
Si tratta di una richiesta AJAX?


getRemoteAddress(): ?string .[method]
-------------------------------------
Restituisce l'indirizzo IP dell'utente. Perché funzioni correttamente può servire [impostare il proxy |configuration#Proxy HTTP].


getRemoteHost(): ?string .[method deprecated]
---------------------------------------------
Deprecato, restituisce sempre `null`. Le ricerche DNS inverse erano lente e inaffidabili; se vi serve il nome host, risolvetelo voi da [getRemoteAddress() |#getRemoteAddress()].


getBasicCredentials(): ?array .[method]
---------------------------------------
Restituisce le credenziali di autenticazione per la [Basic HTTP authentication |https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication].

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


getRawBody(): ?string .[method]
-------------------------------
Restituisce il corpo della richiesta HTTP.

```php
$body = $httpRequest->getRawBody();
```


getOrigin(): ?UrlImmutable .[method]
------------------------------------
Restituisce l'origine da cui è arrivata la richiesta. Un'origine è composta da schema (protocollo), nome host e porta, per esempio `https://example.com:8080`. Restituisce `null` se l'header origin non è presente oppure è impostato a `'null'`.

```php
$origin = $httpRequest->getOrigin();
echo $origin; // https://example.com:8080
echo $origin?->getHost(); // example.com
```

Il browser invia l'header `Origin` in questi casi:
- richieste cross-origin (chiamate AJAX verso un dominio diverso)
- richieste POST, PUT, DELETE e altre che modificano
- richieste fatte con la Fetch API

Il browser NON invia l'header `Origin` per:
- normali richieste GET verso lo stesso dominio (navigazione same-origin)
- navigazione diretta digitando un URL nella barra degli indirizzi
- richieste da client che non sono browser

.[note]
A differenza dell'header `Referer`, `Origin` contiene solo schema, host e porta, non l'intero percorso dell'URL. Questo lo rende più adatto ai controlli di sicurezza preservando la privacy dell'utente. L'header `Origin` si usa soprattutto per la validazione [CORS |nette:glossary#Cross-Origin Resource Sharing (CORS)] (Cross-Origin Resource Sharing).


detectLanguage(array $langs): ?string .[method]
-----------------------------------------------
Rileva la lingua. Come parametro `$langs` passate un array di lingue supportate dall'applicazione e restituirà quella preferita dal browser del visitatore. Non è magia, usa solo l'header `Accept-Language`. Se non trova corrispondenze, restituisce `null`.

```php
// il browser invia per esempio Accept-Language: cs,en-us;q=0.8,en;q=0.5,sl;q=0.3

$langs = ['hu', 'pl', 'en']; // lingue supportate dall'applicazione
echo $httpRequest->detectLanguage($langs); // en
```


RequestFactory
==============

La classe [api:Nette\Http\RequestFactory] serve a creare un'istanza di `Nette\Http\Request`, che rappresenta la richiesta HTTP corrente. (Se lavorate con Nette, l'oggetto della richiesta HTTP viene creato automaticamente dal framework.)

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

Il metodo `fromGlobals()` crea l'oggetto della richiesta in base alle attuali variabili globali di PHP (`$_GET`, `$_POST`, `$_COOKIE`, `$_FILES` e `$_SERVER`). Quando crea l'oggetto, ripulisce automaticamente tutti i parametri in ingresso (GET, POST, COOKIE) e anche l'URL dai caratteri di controllo e dalle sequenze UTF-8 non valide, il che garantisce sicurezza nel lavoro successivo con questi dati.

RequestFactory si può configurare prima di chiamare `fromGlobals()`:

- il metodo `$factory->setBinary()` disattiva la pulizia automatica dei parametri in ingresso dai caratteri di controllo e dalle sequenze UTF-8 non valide.
- il metodo `$factory->setProxy(...)` indica l'indirizzo IP del [server proxy |configuration#Proxy HTTP], necessario per rilevare correttamente l'indirizzo IP dell'utente.
- il metodo `$factory->setForceHttps()` .{data-version:3.3.4} forza lo schema della richiesta a HTTPS indipendentemente dall'ambiente del server.

RequestFactory permette di definire filtri che trasformano automaticamente parti dell'URL della richiesta. Questi filtri rimuovono dagli URL i caratteri indesiderati che vi possono essere finiti per esempio a causa di implementazioni sbagliate dei sistemi di commenti su vari siti:

```php
// rimuove gli spazi dal percorso
$requestFactory->urlFilters['path']['%20'] = '';

// rimuove il punto, la virgola o la parentesi chiusa dalla fine dell'URI
$requestFactory->urlFilters['url']['[.,)]$'] = '';

// ripulisce il percorso dalle doppie barre (filtro predefinito)
$requestFactory->urlFilters['path']['/{2,}'] = '/';
```

La prima chiave, `'path'` oppure `'url'`, determina a quale parte dell'URL verrà applicato il filtro. La seconda chiave è l'espressione regolare da cercare e il valore è la sostituzione da usare al posto del testo trovato.


File caricati
=============

Il metodo `Nette\Http\Request::getFiles()` restituisce un array di tutti gli upload in una struttura normalizzata, le cui foglie sono oggetti [api:Nette\Http\FileUpload]. Essi incapsulano i dati inviati dall'elemento di form `<input type=file>`.

La struttura rispecchia i nomi degli elementi in HTML. Nel caso più semplice può essere un singolo elemento di form con un nome, inviato come:

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

In questo caso `$request->getFiles()` restituisce l'array:

```php
[
	'avatar' => /* istanza di FileUpload */
]
```

L'oggetto `FileUpload` viene creato anche se l'utente non ha caricato alcun file o se l'upload è fallito. Il metodo `hasFile()` restituisce true se un file è stato inviato:

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

Nel caso di un nome di elemento che usa la notazione ad array:

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

l'albero restituito appare così:

```php
[
	'my-form' => [
		'details' => [
			'avatar' => /* istanza di FileUpload */
		],
	],
]
```

Potete anche creare array di file:

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

In tal caso la struttura appare così:

```php
[
	'my-form' => [
		'details' => [
			'avatars' => [
				0 => /* istanza di FileUpload */,
				1 => /* istanza di FileUpload */,
				2 => /* istanza di FileUpload */,
			],
		],
	],
]
```

Il modo migliore di accedere all'indice 1 dell'array annidato è questo:

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

Poiché non potete fidarvi dei dati esterni e quindi contare sulla struttura dei file, questo approccio è più sicuro di per esempio `$request->getFiles()['my-form']['details']['avatars'][1]`, che potrebbe fallire.


Panoramica dei metodi di `FileUpload` .{toc: FileUpload}
--------------------------------------------------------


hasFile(): bool .[method]
-------------------------
Restituisce `true` se l'utente ha caricato un file.


isOk(): bool .[method]
----------------------
Restituisce `true` se il file è stato caricato con successo.


getError(): int .[method]
-------------------------
Restituisce il codice di errore associato al file caricato. È una delle costanti [UPLOAD_ERR_XXX |https://php.net/manual/en/features.file-upload.errors.php]. Se il file è stato caricato con successo, restituisce `UPLOAD_ERR_OK`.


move(string $dest) .[method]
----------------------------
Sposta il file caricato in una nuova posizione. Se il file di destinazione esiste già, verrà sovrascritto.

```php
$file->move('/percorso/verso/i/file/nome.ext');
```


getContents(): ?string .[method]
--------------------------------
Restituisce il contenuto del file caricato. Se l'upload non è riuscito, restituisce `null`.


getContentType(): ?string .[method]
-----------------------------------
Rileva il tipo MIME del contenuto del file caricato in base alla sua firma. Se l'upload non è riuscito o il rilevamento è fallito, restituisce `null`.

.[caution]
Richiede l'estensione PHP `fileinfo`.


getUntrustedName(): string .[method]
------------------------------------
Restituisce il nome originale del file così come lo ha inviato il browser.

.[caution]
Non fidatevi del valore restituito da questo metodo. Un client potrebbe inviare un nome di file malevolo con l'intento di danneggiare o violare la vostra applicazione.


getSanitizedName(): string .[method]
------------------------------------
Restituisce il nome del file sanificato. Contiene solo caratteri ASCII `[a-zA-Z0-9.-]`. Se il nome non contiene caratteri di questo tipo, restituisce `'unknown'`. Se il file è un'immagine JPEG, PNG, GIF, WebP o AVIF, restituisce anche l'estensione corretta.

.[caution]
Richiede l'estensione PHP `fileinfo`.


getSuggestedExtension(): ?string .[method]{data-version:3.2.4}
--------------------------------------------------------------
Restituisce l'estensione di file appropriata (senza il punto) corrispondente al tipo MIME rilevato.

.[caution]
Richiede l'estensione PHP `fileinfo`.


getUntrustedFullPath(): string .[method]
----------------------------------------
Restituisce il percorso originale del file così come lo ha inviato il browser durante l'upload di una directory. Il percorso completo è disponibile solo in PHP 8.1 e successivi. Nelle versioni precedenti questo metodo restituisce il nome originale del file.

.[caution]
Non fidatevi del valore restituito da questo metodo. Un client potrebbe inviare un nome di file malevolo con l'intento di danneggiare o violare la vostra applicazione.


getSize(): int .[method]
------------------------
Restituisce la dimensione del file caricato. Se l'upload non è riuscito, restituisce `0`.


getTemporaryFile(): string .[method]
------------------------------------
Restituisce il percorso della posizione temporanea del file caricato. Se l'upload non è riuscito, restituisce `''`.


__toString(): string .[method]
------------------------------
Restituisce il percorso della posizione temporanea del file caricato. Questo permette di usare l'oggetto `FileUpload` direttamente come stringa.


isImage(): bool .[method]
-------------------------
Restituisce `true` se il file caricato è un'immagine JPEG, PNG, GIF, WebP o AVIF. Il rilevamento si basa sulla sua firma e non verifica l'integrità dell'intero file. Se un'immagine sia danneggiata lo si può scoprire per esempio provando a [caricarla |#toImage()].

.[caution]
Richiede l'estensione PHP `fileinfo`.


getImageSize(): ?array .[method]
--------------------------------
Restituisce la coppia `[larghezza, altezza]` con le dimensioni dell'immagine caricata. Se l'upload non è riuscito o non si tratta di un'immagine valida, restituisce `null`.


toImage(): Nette\Utils\Image .[method]
--------------------------------------
Carica l'immagine come oggetto [Image |utils:images]. Se l'upload non è riuscito o non si tratta di un'immagine valida, lancia una `Nette\Utils\ImageException`.

Richiesta HTTP

Nette incapsula la richiesta HTTP in oggetti con un'API chiara e offre allo stesso tempo un filtro di sanificazione.

La richiesta HTTP è rappresentata dall'oggetto Nette\Http\Request. Se lavorate con Nette, questo oggetto viene creato automaticamente dal framework e potete farvelo passare con la dependency injection. Nei presenter basta chiamare il metodo $this->getHttpRequest(). Se lavorate fuori dal Nette Framework, potete creare l'oggetto con RequestFactory.

Un grande vantaggio di Nette è che, quando crea l'oggetto, sanifica automaticamente tutti i parametri in ingresso (GET, POST, COOKIE) e anche l'URL, rimuovendo i caratteri di controllo e le sequenze UTF-8 non valide. Con questi dati potete poi lavorare in sicurezza. I dati sanificati vengono usati in seguito nei presenter e nei form.

Installazione e requisiti

Nette\Http\Request

Questo oggetto è immutabile. Non ha setter, ha un solo cosiddetto wither, withUrl(), che non modifica l'oggetto ma restituisce una nuova istanza con il valore modificato.

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

Restituisce un clone con un URL diverso.

getUrl(): Nette\Http\UrlScript

Restituisce l'URL della richiesta come oggetto UrlScript.

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

Attenzione: i browser non inviano il frammento al server, quindi $url->getFragment() restituirà una stringa vuota.

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

Restituisce i parametri della richiesta GET.

$all = $httpRequest->getQuery();    // array di tutti i parametri dell'URL
$id = $httpRequest->getQuery('id'); // restituisce il parametro GET 'id' (oppure null)

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

Restituisce i parametri della richiesta POST.

$all = $httpRequest->getPost();     // array di tutti i parametri POST
$id = $httpRequest->getPost('id');  // restituisce il parametro POST 'id' (oppure null)

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

Restituisce un upload come oggetto Nette\Http\FileUpload:

$file = $httpRequest->getFile('avatar');
if ($file?->hasFile()) { // è stato caricato qualche file?
	$file->getUntrustedName(); // nome del file inviato dall'utente
	$file->getSanitizedName(); // nome senza caratteri pericolosi
}

Per accedere a una struttura annidata indicate un array di chiavi.

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

Poiché non potete fidarvi dei dati esterni e quindi contare sulla struttura dei file, questo approccio è più sicuro di per esempio $request->getFiles()['my-form']['details']['avatar'], che potrebbe fallire.

getFiles(): array

Restituisce un albero di tutti gli upload in una struttura normalizzata, le cui foglie sono oggetti Nette\Http\FileUpload:

$files = $httpRequest->getFiles();

getCookie(string $key): ?string

Restituisce un cookie oppure null se non esiste.

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

getCookies(): array

Restituisce tutti i cookie.

$cookies = $httpRequest->getCookies();

getMethod(): string

Restituisce il metodo HTTP con cui è stata fatta la richiesta.

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

isMethod(string $method)bool

Verifica il metodo HTTP con cui è stata fatta la richiesta. Il parametro non fa distinzione tra maiuscole e minuscole.

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

getHeader(string $header): ?string

Restituisce un header HTTP oppure null se non esiste. Il parametro non fa distinzione tra maiuscole e minuscole.

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

getHeaders(): array<string, string>

Restituisce tutti gli header HTTP come array associativo. Le chiavi sono normalizzate in minuscolo.

$headers = $httpRequest->getHeaders();
echo $headers['content-type'];

isSecured(): bool

La connessione è cifrata (HTTPS)? Perché funzioni correttamente può servire impostare il proxy.

isSameSite(): bool

La richiesta proviene dallo stesso sito? Dalla versione 3.4 è sostituito dal più capace isFrom().

isFrom(FetchSite|array $site, FetchDest|array|null $dest=null, ?bool $user=null)bool

Vi dice da dove è arrivata la richiesta e in che modo il browser l'ha fatta, in base agli header Sec-Fetch-* (i cosiddetti Fetch Metadata) che il browser imposta da sé e che una pagina in esecuzione nel browser della vittima non può né falsificare né rimuovere. Nette lo usa internamente per proteggere automaticamente form e segnali dal Cross-Site Request Forgery (CSRF). Torna utile quando volete proteggere vostre azioni sensibili, per esempio endpoint di API o link distruttivi.

Il metodo restituisce true solo quando la richiesta soddisfa tutte le condizioni che indicate. Il primo parametro $site descrive la relazione tra la pagina che ha originato la richiesta e il vostro sito (l'header Sec-Fetch-Site). Accetta un singolo valore o un elenco di questi casi di FetchSite:

  • FetchSite::SameOrigin – dalla stessa identica origine (schema, host e porta)
  • FetchSite::SameSite – dallo stesso sito, eventualmente da un sottodominio diverso
  • FetchSite::CrossSite – da un sito estraneo
  • FetchSite::None – l'ha originata direttamente l'utente, per esempio digitando l'URL o aprendo un segnalibro
// la richiesta proviene dalle nostre pagine?
if (!$httpRequest->isFrom([FetchSite::SameOrigin, FetchSite::SameSite])) {
	// blocchiamo l'azione
}

Il parametro opzionale $dest (l'header Sec-Fetch-Dest) dice che tipo di risorsa il browser sta scaricando, per esempio FetchDest::Document per una navigazione di primo livello oppure FetchDest::Empty per una richiesta fatta da JavaScript. Il parametro opzionale $user (l'header Sec-Fetch-User) indica se la navigazione è stata provocata da una vera azione dell'utente, come cliccare un link o inviare un form; passate true per richiederlo.

Un controllo che un'azione sia raggiungibile solo dalle vostre pagine e solo tramite una vera azione dell'utente appare allora così:

if (!$httpRequest->isFrom(FetchSite::SameOrigin, FetchDest::Document, user: true)) {
	$this->error();
}

I browser più vecchi (Safari prima della 16.4) non inviano gli header Sec-Fetch-*. Per essi Nette ripiega su un cookie SameSite=Strict che prova solo che la richiesta non è cross-site. Un controllo che richieda anche $dest o $user non si può verificare in questo modo e in quei browser restituisce false: se è troppo severo, verificate solo $site.

isAjax(): bool

Si tratta di una richiesta AJAX?

getRemoteAddress(): ?string

Restituisce l'indirizzo IP dell'utente. Perché funzioni correttamente può servire impostare il proxy.

getRemoteHost(): ?string

Deprecato, restituisce sempre null. Le ricerche DNS inverse erano lente e inaffidabili; se vi serve il nome host, risolvetelo voi da getRemoteAddress().

getBasicCredentials(): ?array

Restituisce le credenziali di autenticazione per la Basic HTTP authentication.

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

getRawBody(): ?string

Restituisce il corpo della richiesta HTTP.

$body = $httpRequest->getRawBody();

getOrigin(): ?UrlImmutable

Restituisce l'origine da cui è arrivata la richiesta. Un'origine è composta da schema (protocollo), nome host e porta, per esempio https://example.com:8080. Restituisce null se l'header origin non è presente oppure è impostato a 'null'.

$origin = $httpRequest->getOrigin();
echo $origin; // https://example.com:8080
echo $origin?->getHost(); // example.com

Il browser invia l'header Origin in questi casi:

  • richieste cross-origin (chiamate AJAX verso un dominio diverso)
  • richieste POST, PUT, DELETE e altre che modificano
  • richieste fatte con la Fetch API

Il browser NON invia l'header Origin per:

  • normali richieste GET verso lo stesso dominio (navigazione same-origin)
  • navigazione diretta digitando un URL nella barra degli indirizzi
  • richieste da client che non sono browser

A differenza dell'header Referer, Origin contiene solo schema, host e porta, non l'intero percorso dell'URL. Questo lo rende più adatto ai controlli di sicurezza preservando la privacy dell'utente. L'header Origin si usa soprattutto per la validazione CORS (Cross-Origin Resource Sharing).

detectLanguage(array $langs): ?string

Rileva la lingua. Come parametro $langs passate un array di lingue supportate dall'applicazione e restituirà quella preferita dal browser del visitatore. Non è magia, usa solo l'header Accept-Language. Se non trova corrispondenze, restituisce null.

// il browser invia per esempio Accept-Language: cs,en-us;q=0.8,en;q=0.5,sl;q=0.3

$langs = ['hu', 'pl', 'en']; // lingue supportate dall'applicazione
echo $httpRequest->detectLanguage($langs); // en

RequestFactory

La classe Nette\Http\RequestFactory serve a creare un'istanza di Nette\Http\Request, che rappresenta la richiesta HTTP corrente. (Se lavorate con Nette, l'oggetto della richiesta HTTP viene creato automaticamente dal framework.)

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

Il metodo fromGlobals() crea l'oggetto della richiesta in base alle attuali variabili globali di PHP ($_GET, $_POST, $_COOKIE, $_FILES e $_SERVER). Quando crea l'oggetto, ripulisce automaticamente tutti i parametri in ingresso (GET, POST, COOKIE) e anche l'URL dai caratteri di controllo e dalle sequenze UTF-8 non valide, il che garantisce sicurezza nel lavoro successivo con questi dati.

RequestFactory si può configurare prima di chiamare fromGlobals():

  • il metodo $factory->setBinary() disattiva la pulizia automatica dei parametri in ingresso dai caratteri di controllo e dalle sequenze UTF-8 non valide.
  • il metodo $factory->setProxy(...) indica l'indirizzo IP del server proxy, necessario per rilevare correttamente l'indirizzo IP dell'utente.
  • il metodo $factory->setForceHttps() .{data-version:3.3.4} forza lo schema della richiesta a HTTPS indipendentemente dall'ambiente del server.

RequestFactory permette di definire filtri che trasformano automaticamente parti dell'URL della richiesta. Questi filtri rimuovono dagli URL i caratteri indesiderati che vi possono essere finiti per esempio a causa di implementazioni sbagliate dei sistemi di commenti su vari siti:

// rimuove gli spazi dal percorso
$requestFactory->urlFilters['path']['%20'] = '';

// rimuove il punto, la virgola o la parentesi chiusa dalla fine dell'URI
$requestFactory->urlFilters['url']['[.,)]$'] = '';

// ripulisce il percorso dalle doppie barre (filtro predefinito)
$requestFactory->urlFilters['path']['/{2,}'] = '/';

La prima chiave, 'path' oppure 'url', determina a quale parte dell'URL verrà applicato il filtro. La seconda chiave è l'espressione regolare da cercare e il valore è la sostituzione da usare al posto del testo trovato.

File caricati

Il metodo Nette\Http\Request::getFiles() restituisce un array di tutti gli upload in una struttura normalizzata, le cui foglie sono oggetti Nette\Http\FileUpload. Essi incapsulano i dati inviati dall'elemento di form <input type=file>.

La struttura rispecchia i nomi degli elementi in HTML. Nel caso più semplice può essere un singolo elemento di form con un nome, inviato come:

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

In questo caso $request->getFiles() restituisce l'array:

[
	'avatar' => /* istanza di FileUpload */
]

L'oggetto FileUpload viene creato anche se l'utente non ha caricato alcun file o se l'upload è fallito. Il metodo hasFile() restituisce true se un file è stato inviato:

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

Nel caso di un nome di elemento che usa la notazione ad array:

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

l'albero restituito appare così:

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

Potete anche creare array di file:

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

In tal caso la struttura appare così:

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

Il modo migliore di accedere all'indice 1 dell'array annidato è questo:

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

Poiché non potete fidarvi dei dati esterni e quindi contare sulla struttura dei file, questo approccio è più sicuro di per esempio $request->getFiles()['my-form']['details']['avatars'][1], che potrebbe fallire.

Panoramica dei metodi di FileUpload

hasFile(): bool

Restituisce true se l'utente ha caricato un file.

isOk(): bool

Restituisce true se il file è stato caricato con successo.

getError(): int

Restituisce il codice di errore associato al file caricato. È una delle costanti UPLOAD_ERR_XXX. Se il file è stato caricato con successo, restituisce UPLOAD_ERR_OK.

move(string $dest)

Sposta il file caricato in una nuova posizione. Se il file di destinazione esiste già, verrà sovrascritto.

$file->move('/percorso/verso/i/file/nome.ext');

getContents(): ?string

Restituisce il contenuto del file caricato. Se l'upload non è riuscito, restituisce null.

getContentType(): ?string

Rileva il tipo MIME del contenuto del file caricato in base alla sua firma. Se l'upload non è riuscito o il rilevamento è fallito, restituisce null.

Richiede l'estensione PHP fileinfo.

getUntrustedName(): string

Restituisce il nome originale del file così come lo ha inviato il browser.

Non fidatevi del valore restituito da questo metodo. Un client potrebbe inviare un nome di file malevolo con l'intento di danneggiare o violare la vostra applicazione.

getSanitizedName(): string

Restituisce il nome del file sanificato. Contiene solo caratteri ASCII [a-zA-Z0-9.-]. Se il nome non contiene caratteri di questo tipo, restituisce 'unknown'. Se il file è un'immagine JPEG, PNG, GIF, WebP o AVIF, restituisce anche l'estensione corretta.

Richiede l'estensione PHP fileinfo.

getSuggestedExtension(): ?string

Restituisce l'estensione di file appropriata (senza il punto) corrispondente al tipo MIME rilevato.

Richiede l'estensione PHP fileinfo.

getUntrustedFullPath(): string

Restituisce il percorso originale del file così come lo ha inviato il browser durante l'upload di una directory. Il percorso completo è disponibile solo in PHP 8.1 e successivi. Nelle versioni precedenti questo metodo restituisce il nome originale del file.

Non fidatevi del valore restituito da questo metodo. Un client potrebbe inviare un nome di file malevolo con l'intento di danneggiare o violare la vostra applicazione.

getSize(): int

Restituisce la dimensione del file caricato. Se l'upload non è riuscito, restituisce 0.

getTemporaryFile(): string

Restituisce il percorso della posizione temporanea del file caricato. Se l'upload non è riuscito, restituisce ''.

__toString(): string

Restituisce il percorso della posizione temporanea del file caricato. Questo permette di usare l'oggetto FileUpload direttamente come stringa.

isImage(): bool

Restituisce true se il file caricato è un'immagine JPEG, PNG, GIF, WebP o AVIF. Il rilevamento si basa sulla sua firma e non verifica l'integrità dell'intero file. Se un'immagine sia danneggiata lo si può scoprire per esempio provando a caricarla.

Richiede l'estensione PHP fileinfo.

getImageSize(): ?array

Restituisce la coppia [larghezza, altezza] con le dimensioni dell'immagine caricata. Se l'upload non è riuscito o non si tratta di un'immagine valida, restituisce null.

toImage(): Nette\Utils\Image

Carica l'immagine come oggetto Image. Se l'upload non è riuscito o non si tratta di un'immagine valida, lancia una Nette\Utils\ImageException.