Requisição HTTP

Nette encapsula a requisição HTTP em objetos com uma API compreensível e, ao mesmo tempo, fornece um filtro de sanitização.

A requisição HTTP é representada pelo objeto Nette\Http\Request. Se trabalha com Nette, este objeto é criado automaticamente pelo framework e pode recebê-lo por meio de injeção de dependência. Nos presenters, basta chamar o método $this->getHttpRequest(). Se trabalha fora do Nette Framework, pode criar o objeto usando RequestFactory.

Uma grande vantagem de Nette é que, ao criar o objeto, ele limpa automaticamente todos os parâmetros de entrada GET, POST, COOKIE e também a URL de caracteres de controlo e sequências UTF-8 inválidas. Com esses dados, pode trabalhar com segurança. Os dados limpos são então usados em presenters e formulários.

Instalação e requisitos

Nette\Http\Request

Este objeto é imutável. Não possui setters, tem apenas um chamado wither withUrl(), que não altera o objeto, mas retorna uma nova instância com o valor alterado.

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

Retorna um clone com uma URL diferente.

getUrl(): Nette\Http\UrlScript

Retorna a URL da requisição como um objeto UrlScript.

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

Aviso: os navegadores não enviam o fragmento para o servidor, então $url->getFragment() retornará uma string vazia.

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

Retorna os parâmetros GET da requisição.

$all = $httpRequest->getQuery(); // retorna um array de todos os parâmetros da URL
$id = $httpRequest->getQuery('id'); // retorna o parâmetro GET 'id' (ou null)

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

Retorna os parâmetros POST da requisição.

$all = $httpRequest->getPost(); // retorna um array de todos os parâmetros do POST
$id = $httpRequest->getPost('id'); // retorna o parâmetro POST 'id' (ou null)

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

Retorna o upload como um objeto Nette\Http\FileUpload:

$file = $httpRequest->getFile('avatar');
if ($file?->hasFile()) { // algum ficheiro foi enviado?
	$file->getUntrustedName(); // nome do ficheiro enviado pelo utilizador
	$file->getSanitizedName(); // nome sem caracteres perigosos
}

Para aceder à estrutura aninhada, forneça um array de chaves.

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

Como não se pode confiar nos dados externos e, portanto, nem na forma da estrutura dos ficheiros, este método é mais seguro do que, por exemplo, $request->getFiles()['my-form']['details']['avatar'], que pode falhar.

getFiles(): array

Retorna a árvore de todos os uploads numa estrutura normalizada, cujas folhas são objetos Nette\Http\FileUpload:

$files = $httpRequest->getFiles();

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

Retorna um cookie ou null se não existir.

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

getCookies(): array

Retorna todos os cookies.

$cookies = $httpRequest->getCookies();

getMethod(): string

Retorna o método HTTP com o qual a requisição foi feita.

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

isMethod (string $method)bool

Testa o método HTTP com o qual a requisição foi feita. O parâmetro é insensível a maiúsculas/minúsculas.

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

getHeader (string $header): ?string

Retorna um cabeçalho HTTP ou null se não existir. O parâmetro é insensível a maiúsculas/minúsculas.

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

getHeaders(): array

Retorna todos os cabeçalhos HTTP como um array associativo.

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

isSecured(): bool

A conexão é criptografada (HTTPS)? Para o funcionamento correto, pode ser necessário configurar o proxy.

isSameSite(): bool

A requisição vem do mesmo (sub)domínio e é iniciada clicando num link? Nette usa o cookie _nss (anteriormente nette-samesite) para deteção.

isAjax(): bool

É uma requisição AJAX?

getRemoteAddress(): ?string

Retorna o endereço IP do utilizador. Para o funcionamento correto, pode ser necessário configurar o proxy.

getRemoteHost(): ?string

Retorna a resolução DNS do endereço IP do utilizador. Para o funcionamento correto, pode ser necessário configurar o proxy.

getBasicCredentials(): ?array

Retorna as credenciais de autenticação para Basic HTTP authentication.

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

getRawBody(): ?string

Retorna o corpo da requisição HTTP.

$body = $httpRequest->getRawBody();

detectLanguage (array $langs): ?string

Deteta o idioma. Como parâmetro $lang, passamos um array com os idiomas que a aplicação suporta, e ela retorna aquele que o navegador do visitante preferiria ver. Não há mágica, apenas o cabeçalho Accept-Language é usado. Se não houver correspondência, retorna null.

// o navegador envia, por exemplo, Accept-Language: cs,en-us;q=0.8,en;q=0.5,sl;q=0.3

$langs = ['hu', 'pl', 'en']; // idiomas suportados pela aplicação
echo $httpRequest->detectLanguage($langs); // en

RequestFactory

A classe Nette\Http\RequestFactory serve para criar uma instância de Nette\Http\Request, que representa a requisição HTTP atual. (Se trabalha com Nette, o objeto da requisição HTTP é criado automaticamente pelo framework.)

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

O método fromGlobals() cria o objeto da requisição com base nas variáveis globais atuais do PHP ($_GET, $_POST, $_COOKIE, $_FILES e $_SERVER). Ao criar o objeto, ele limpa automaticamente todos os parâmetros de entrada GET, POST, COOKIE e também a URL de caracteres de controlo e sequências UTF-8 inválidas, o que garante a segurança ao trabalhar posteriormente com esses dados.

A RequestFactory pode ser configurada antes de chamar fromGlobals():

  • com o método $factory->setBinary(), desativa a limpeza automática dos parâmetros de entrada de caracteres de controlo e sequências UTF-8 inválidas.
  • com o método $factory->setProxy(...), indica o endereço IP do servidor proxy, o que é necessário para a deteção correta do endereço IP do utilizador.

A RequestFactory permite definir filtros que transformam automaticamente partes da URL da requisição. Esses filtros removem caracteres indesejados da URL, que podem ser inseridos lá, por exemplo, por implementações incorretas de sistemas de comentários em vários sites:

// remoção de espaços do caminho
$requestFactory->urlFilters['path']['%20'] = '';

// remoção de ponto, vírgula ou parêntese direito do final da URI
$requestFactory->urlFilters['url']['[.,)]$'] = '';

// limpeza do caminho de barras duplicadas (filtro padrão)
$requestFactory->urlFilters['path']['/{2,}'] = '/';

A primeira chave 'path' ou 'url' determina a qual parte da URL o filtro se aplica. A segunda chave é a expressão regular a ser pesquisada, e o valor é a substituição a ser usada no lugar do texto encontrado.

Upload de ficheiros

O método Nette\Http\Request::getFiles() retorna um array de todos os uploads numa estrutura normalizada, cujas folhas são objetos Nette\Http\FileUpload. Eles encapsulam os dados enviados pelo controlo de formulário <input type=file>.

A estrutura reflete a nomenclatura dos controlos em HTML. No caso mais simples, pode ser um único elemento de formulário nomeado enviado como:

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

Neste caso, $request->getFiles() retorna um array:

[
	'avatar' => /* Instância FileUpload */
]

O objeto FileUpload é criado mesmo que o utilizador não tenha enviado nenhum ficheiro ou o envio tenha falhado. Se o ficheiro foi enviado é retornado pelo método hasFile():

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

No caso do nome do elemento usando a notação de array:

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

a árvore retornada parece-se com isto:

[
	'my-form' => [
		'details' => [
			'avatar' => /* Instância FileUpload */
		],
	],
]

Também é possível criar um array de ficheiros:

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

Nesse caso, a estrutura parece-se com isto:

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

A melhor maneira de aceder ao índice 1 do array aninhado é assim:

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

Como não se pode confiar nos dados externos e, portanto, nem na forma da estrutura dos ficheiros, este método é mais seguro do que, por exemplo, $request->getFiles()['my-form']['details']['avatars'][1], que pode falhar.

Visão geral dos métodos FileUpload

hasFile(): bool

Retorna true se o utilizador enviou algum ficheiro.

isOk(): bool

Retorna true se o ficheiro foi carregado com sucesso.

getError(): int

Retorna o código de erro durante o upload do ficheiro. É uma das constantes UPLOAD_ERR_XXX. Caso o upload tenha ocorrido corretamente, retorna UPLOAD_ERR_OK.

move (string $dest)

Move o ficheiro carregado para um novo local. Se o ficheiro de destino já existir, ele será sobrescrito.

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

getContents(): ?string

Retorna o conteúdo do ficheiro carregado. Caso o upload não tenha sido bem-sucedido, retorna null.

getContentType(): ?string

Deteta o tipo de conteúdo MIME do ficheiro carregado com base na sua assinatura. Caso o upload não tenha sido bem-sucedido ou a deteção falhe, retorna null.

Requer a extensão PHP fileinfo.

getUntrustedName(): string

Retorna o nome original do ficheiro, como enviado pelo navegador.

Não confie no valor retornado por este método. O cliente pode ter enviado um nome de ficheiro malicioso com a intenção de danificar ou hackear a sua aplicação.

getSanitizedName(): string

Retorna o nome do ficheiro sanitizado. Contém apenas caracteres ASCII [a-zA-Z0-9.-]. Se o nome não contiver tais caracteres, retorna 'unknown'. Se o ficheiro for uma imagem no formato JPEG, PNG, GIF, WebP ou AVIF, retorna também a extensão correta.

Requer a extensão PHP fileinfo.

getSuggestedExtension(): ?string

Retorna a extensão de ficheiro apropriada (sem o ponto) correspondente ao tipo MIME detetado.

Requer a extensão PHP fileinfo.

getUntrustedFullPath(): string

Retorna o caminho original do ficheiro, como enviado pelo navegador ao fazer upload de uma pasta. O caminho completo está disponível apenas no PHP 8.1 e superior. Em versões anteriores, este método retorna o nome original do ficheiro.

Não confie no valor retornado por este método. O cliente pode ter enviado um nome de ficheiro malicioso com a intenção de danificar ou hackear a sua aplicação.

getSize(): int

Retorna o tamanho do ficheiro carregado. Caso o upload não tenha sido bem-sucedido, retorna 0.

getTemporaryFile(): string

Retorna o caminho para o local temporário do ficheiro carregado. Caso o upload não tenha sido bem-sucedido, retorna ''.

isImage(): bool

Retorna true se o ficheiro carregado for uma imagem no formato JPEG, PNG, GIF, WebP ou AVIF. A deteção ocorre com base na sua assinatura e não verifica a integridade de todo o ficheiro. Se a imagem não está danificada pode ser verificado, por exemplo, tentando carregá-la.

Requer a extensão PHP fileinfo.

getImageSize(): ?array

Retorna o par [largura, altura] com as dimensões da imagem carregada. Caso o upload não tenha sido bem-sucedido ou não seja uma imagem válida, retorna null.

toImage(): Nette\Utils\Image

Carrega a imagem como um objeto Image. Caso o upload não tenha sido bem-sucedido ou não seja uma imagem válida, lança a exceção Nette\Utils\ImageException.

versão: 4.0