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