Petición HTTP
Nette encapsula la petición HTTP en objetos con una API comprensible y, al mismo tiempo, proporciona un filtro de sanitización.
La petición HTTP está representada por el objeto Nette\Http\Request. Si trabaja con Nette, este objeto es
creado automáticamente por el framework y puede solicitar que se le pase mediante inyección de dependencias. En los presenters, basta
con llamar al método $this->getHttpRequest()
. Si trabaja fuera del Nette Framework, puede crear el objeto usando
RequestFactory.
Una gran ventaja de Nette es que al crear el objeto, limpia automáticamente todos los parámetros de entrada GET, POST, COOKIE y también la URL de caracteres de control y secuencias UTF-8 inválidas. Con estos datos, puede trabajar de forma segura. Los datos limpios se utilizan posteriormente en presenters y formularios.
Nette\Http\Request
Este objeto es inmutable. No tiene setters, solo tiene un llamado wither withUrl()
, que no modifica el objeto,
sino que devuelve una nueva instancia con el valor cambiado.
withUrl (Nette\Http\UrlScript $url): Nette\Http\Request
Devuelve un clon con una URL diferente.
getUrl(): Nette\Http\UrlScript
Devuelve la URL de la petición como un objeto UrlScript.
$url = $httpRequest->getUrl();
echo $url; // https://doc.nette.org/es/?action=edit
echo $url->getHost(); // nette.org
Advertencia: los navegadores no envían el fragmento al servidor, por lo que $url->getFragment()
devolverá una
cadena vacía.
getQuery (?string $key=null): string|array|null
Devuelve los parámetros GET de la petición.
$all = $httpRequest->getQuery(); // devuelve un array de todos los parámetros de la URL
$id = $httpRequest->getQuery('id'); // devuelve el parámetro GET 'id' (o null)
getPost (?string $key=null): string|array|null
Devuelve los parámetros POST de la petición.
$all = $httpRequest->getPost(); // devuelve un array de todos los parámetros de POST
$id = $httpRequest->getPost('id'); // devuelve el parámetro POST 'id' (o null)
getFile (string|string[] $key): Nette\Http\FileUpload|array|null
Devuelve la carga como un objeto Nette\Http\FileUpload:
$file = $httpRequest->getFile('avatar');
if ($file?->hasFile()) { // ¿se ha cargado algún archivo?
$file->getUntrustedName(); // nombre del archivo enviado por el usuario
$file->getSanitizedName(); // nombre sin caracteres peligrosos
}
Para acceder a una estructura anidada, proporcione un array de claves.
//<input type="file" name="my-form[details][avatar]" multiple>
$file = $request->getFile(['my-form', 'details', 'avatar']);
Dado que no se puede confiar en los datos externos y, por lo tanto, tampoco en la forma de la estructura de archivos, este
método es más seguro que, por ejemplo, $request->getFiles()['my-form']['details']['avatar']
, que podría
fallar.
getFiles(): array
Devuelve el árbol de todas las cargas en una estructura normalizada, cuyas hojas son objetos Nette\Http\FileUpload:
$files = $httpRequest->getFiles();
getCookie (string $key): string|array|null
Devuelve la cookie o null
si no existe.
$sessId = $httpRequest->getCookie('sess_id');
getCookies(): array
Devuelve todas las cookies.
$cookies = $httpRequest->getCookies();
getMethod(): string
Devuelve el método HTTP con el que se realizó la petición.
$httpRequest->getMethod(); // GET, POST, HEAD, PUT
isMethod (string $method): bool
Comprueba el método HTTP con el que se realizó la petición. El parámetro es insensible a mayúsculas/minúsculas.
if ($httpRequest->isMethod('GET')) // ...
getHeader (string $header): ?string
Devuelve una cabecera HTTP o null
si no existe. El parámetro es insensible a mayúsculas/minúsculas.
$userAgent = $httpRequest->getHeader('User-Agent');
getHeaders(): array
Devuelve todas las cabeceras HTTP como un array asociativo.
$headers = $httpRequest->getHeaders();
echo $headers['Content-Type'];
isSecured(): bool
¿Está la conexión cifrada (HTTPS)? Para un funcionamiento correcto, puede ser necesario configurar un proxy.
isSameSite(): bool
¿Proviene la petición del mismo (sub)dominio y se inicia haciendo clic en un enlace? Nette utiliza la cookie
_nss
(anteriormente nette-samesite
) para la detección.
isAjax(): bool
¿Es una petición AJAX?
getRemoteAddress(): ?string
Devuelve la dirección IP del usuario. Para un funcionamiento correcto, puede ser necesario configurar un proxy.
getRemoteHost(): ?string
Devuelve la resolución DNS de la dirección IP del usuario. Para un funcionamiento correcto, puede ser necesario configurar un proxy.
getBasicCredentials(): ?array
Devuelve las credenciales de autenticación para Basic HTTP authentication. Devuelve un array
[nombre de usuario, contraseña]
o null
.
[$user, $password] = $httpRequest->getBasicCredentials() ?? [null, null];
getRawBody(): ?string
Devuelve el cuerpo de la petición HTTP.
$body = $httpRequest->getRawBody();
detectLanguage (array $langs): ?string
Detecta el idioma. Como parámetro $langs
, pasamos un array con los idiomas que soporta la aplicación, y devuelve
el que el navegador del visitante preferiría. No es magia, simplemente utiliza la cabecera Accept-Language
. Si no
hay coincidencia, devuelve null
.
// el navegador envía p. ej. Accept-Language: es-ES,es;q=0.9,en;q=0.8
$langs = ['hu', 'pl', 'en']; // idiomas soportados por la aplicación
echo $httpRequest->detectLanguage($langs); // en
RequestFactory
La clase Nette\Http\RequestFactory sirve para
crear una instancia de Nette\Http\Request
, que representa la petición HTTP actual. (Si trabaja con Nette, el objeto
de la petición HTTP es creado automáticamente por el framework).
$factory = new Nette\Http\RequestFactory;
$httpRequest = $factory->fromGlobals();
El método fromGlobals()
crea el objeto de la petición basándose en las variables globales actuales de PHP
($_GET
, $_POST
, $_COOKIE
, $_FILES
y $_SERVER
). Al crear el
objeto, limpia automáticamente todos los parámetros de entrada GET, POST, COOKIE y también la URL de caracteres de control y
secuencias UTF-8 inválidas, lo que garantiza la seguridad al trabajar posteriormente con estos datos.
RequestFactory se puede configurar antes de llamar a fromGlobals()
:
- con el método
$factory->setBinary()
desactiva la limpieza automática de los parámetros de entrada de caracteres de control y secuencias UTF-8 inválidas. - con el método
$factory->setProxy(...)
indica la dirección IP del servidor proxy, lo cual es necesario para la correcta detección de la dirección IP del usuario.
RequestFactory permite definir filtros que transforman automáticamente partes de la URL de la petición. Estos filtros eliminan caracteres no deseados de la URL, que pueden haber sido insertados allí, por ejemplo, por una implementación incorrecta de sistemas de comentarios en varios sitios web:
// eliminación de espacios de la ruta
$requestFactory->urlFilters['path']['%20'] = '';
// eliminación de punto, coma o paréntesis derecho del final de la URI
$requestFactory->urlFilters['url']['[.,)]$'] = '';
// limpieza de la ruta de barras dobles (filtro por defecto)
$requestFactory->urlFilters['path']['/{2,}'] = '/';
La primera clave 'path'
o 'url'
determina a qué parte de la URL se aplica el filtro. La segunda
clave es la expresión regular que se debe buscar, y el valor es el reemplazo que se utilizará en lugar del texto encontrado.
Archivos cargados
El método Nette\Http\Request::getFiles()
devuelve un array de todas las cargas en una estructura normalizada,
cuyas hojas son objetos Nette\Http\FileUpload. Estos
encapsulan los datos enviados por el elemento de formulario <input type=file>
.
La estructura refleja la nomenclatura de los elementos en HTML. En el caso más simple, puede ser un único elemento de formulario con nombre enviado como:
<input type="file" name="avatar">
En este caso, $request->getFiles()
devuelve un array:
[
'avatar' => /* instancia de FileUpload */
]
El objeto FileUpload
se crea incluso si el usuario no envió ningún archivo o el envío falló. Si se envió un
archivo lo devuelve el método hasFile()
:
$request->getFile('avatar')?->hasFile();
En el caso de un nombre de elemento que utiliza la notación de array:
<input type="file" name="my-form[details][avatar]">
el árbol devuelto se ve así:
[
'my-form' => [
'details' => [
'avatar' => /* instancia de FileUpload */
],
],
]
También se puede crear un array de archivos:
<input type="file" name="my-form[details][avatars][]" multiple>
En tal caso, la estructura se ve así:
[
'my-form' => [
'details' => [
'avatars' => [
0 => /* instancia de FileUpload */,
1 => /* instancia de FileUpload */,
2 => /* instancia de FileUpload */,
],
],
],
]
La mejor manera de acceder al índice 1 del array anidado es así:
$file = $request->getFile(['my-form', 'details', 'avatars', 1]);
if ($file instanceof FileUpload) {
// ...
}
Dado que no se puede confiar en los datos externos y, por lo tanto, tampoco en la forma de la estructura de archivos, este
método es más seguro que, por ejemplo, $request->getFiles()['my-form']['details']['avatars'][1]
, que podría
fallar.
Resumen de métodos FileUpload
hasFile(): bool
Devuelve true
si el usuario ha cargado algún archivo.
isOk(): bool
Devuelve true
si el archivo se cargó correctamente.
getError(): int
Devuelve el código de error de la carga del archivo. Es una de las constantes UPLOAD_ERR_XXX. Si la carga fue exitosa, devuelve
UPLOAD_ERR_OK
.
move (string $dest)
Mueve el archivo cargado a una nueva ubicación. Si el archivo de destino ya existe, será sobrescrito.
$file->move('/path/to/files/name.ext');
getContents(): ?string
Devuelve el contenido del archivo cargado. Si la carga no fue exitosa, devuelve null
.
getContentType(): ?string
Detecta el tipo de contenido MIME del archivo cargado basándose en su firma. Si la carga no fue exitosa o la detección
falló, devuelve null
.
Requiere la extensión PHP fileinfo
.
getUntrustedName(): string
Devuelve el nombre original del archivo, tal como lo envió el navegador.
No confíe en el valor devuelto por este método. Un cliente podría haber enviado un nombre de archivo malicioso con la intención de dañar o hackear su aplicación.
getSanitizedName(): string
Devuelve el nombre del archivo sanitizado. Contiene solo caracteres ASCII [a-zA-Z0-9.-]
. Si el nombre no contiene
tales caracteres, devuelve 'unknown'
. Si el archivo es una imagen en formato JPEG, PNG, GIF, WebP o AVIF, también
devuelve la extensión correcta.
Requiere la extensión PHP fileinfo
.
getSuggestedExtension(): ?string
Devuelve la extensión de archivo apropiada (sin el punto) correspondiente al tipo MIME detectado.
Requiere la extensión PHP fileinfo
.
getUntrustedFullPath(): string
Devuelve la ruta original del archivo, tal como la envió el navegador al cargar una carpeta. La ruta completa solo está disponible en PHP 8.1 y superior. En versiones anteriores, este método devuelve el nombre original del archivo.
No confíe en el valor devuelto por este método. Un cliente podría haber enviado un nombre de archivo malicioso con la intención de dañar o hackear su aplicación.
getSize(): int
Devuelve el tamaño del archivo cargado. Si la carga no fue exitosa, devuelve 0
.
getTemporaryFile(): string
Devuelve la ruta a la ubicación temporal del archivo cargado. Si la carga no fue exitosa, devuelve ''
.
isImage(): bool
Devuelve true
si el archivo cargado es una imagen en formato JPEG, PNG, GIF, WebP o AVIF. La detección se basa
en su firma y no verifica la integridad de todo el archivo. Si una imagen está dañada se puede detectar, por ejemplo, intentando
cargarla.
Requiere la extensión PHP fileinfo
.
getImageSize(): ?array
Devuelve un par [ancho, alto]
con las dimensiones de la imagen cargada. Si la carga no fue exitosa o no es una
imagen válida, devuelve null
.
toImage(): Nette\Utils\Image
Carga la imagen como un objeto Image. Si la carga no fue exitosa o no es
una imagen válida, lanza una excepción Nette\Utils\ImageException
.