Requests
Requests
La clase Illuminate\Http\Request provee una forma orienta a objetos de interactuar con la actual request que es manejada por nuestra aplicación, de la misma que recuperar el input, cookies y los archivos enviados en la request.
Interacting With The Request
Accessing the Request
Para obtener una instancia de la actual request, podemos recuperarla en la ruta o el contrador marcandola como dependencia:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* Store a new user.
*/
public function store(Request $request): RedirectResponse
{
$name = $request->input('name');
// Store the user...
return redirect('/users');
}
}
Y como mencionamos, también en la closure definida en la ruta:
use Illuminate\Http\Request;
Route::get('/', function (Request $request) {
// ...
});
Dependency Injection and Route Parameters
Se puede combinar el inyectar la Request con obtener también los parámetros de la ruta
use App\Http\Controllers\UserController;
Route::put('/user/{id}', [UserController::class, 'update']);
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* Update the specified user.
*/
public function update(Request $request, string $id): RedirectResponse
{
// Update the user...
return redirect('/users');
}
}
Request Path, Host, and Method
La instancia de Illuminate\Http\Request provee una variedad de métodos para examinar
la actual request y que hereda de Symfony\Component\HttpFoundation\Request
Retrieving the Request Path
El método path devuelve información del path de la request. Por lo que si la request entrante apunta a http://example.com/foo/bar , el pathdevolveria foo/bar
$uri = $request->path();
Inspecting the Request Path / Route
El método ispermite verificar que la request entrante coincide con un determinado patrón. Puedes usar el * como comodín.
if ($request->is('admin/*')) {
// ...
}
Usando routeIs puedes determinar si la request entrante coincide con el nombre de la ruta (named routes):
if ($request->routeIs('admin.*')) {
// ...
}
Retrieving the Request URL
Para recuperar la URL entera de la request entrante puedes usar url o fullUrl
El método url devolverá la cadena sin los query params mientras que fullUrl incluye también los query params.
$url = $request->url();
$urlWithQueryString = $request->fullUrl();
Si quieres agregar al final (append), puedes usar fullUrlWithQuery pasando un array:
$request->fullUrlWithQuery(['type' => 'phone']);
Si quieres recuperar la URL actual sin un query param en concreto puedes usar:
$request->fullUrlWithoutQuery(['type']);
Retrieving the Request Host
Puedes recuperar el “host” de la request entrante usando host , httpHost y schemeAndHttpHost
$request->host();
$request->httpHost();
$request->schemeAndHttpHost();
Retrieving the Request Method
El método method devuelve el HTTP verb. Si necesitas comprobar que sea uno en concreto puedes usar:
$method = $request->method();
if ($request->isMethod('post')) {
// ...
}
Request Headers
Puedes recuperar los encabezados de la request de la instancia Illuminate\Http\Request usando el método header .
$value = $request->header('X-Header-Name');
$value = $request->header('X-Header-Name', 'default');
El método hasHeaderse puede usar para determinar si la request tiene un header en concreto:
if ($request->hasHeader('X-Header-Name')) {
// ...
}
Por conveniencia, el método bearerTokense puede usar para recuperar el bearer token del encabezado Authorization
Request IP Address
El método ip se utiliza para recuperar la dirección ip:
$ipAddress = $request->ip();
Si deseas recuperar un array de ips con todas las direcciones por los que el usuario fue redireccionado por los proxies, puedes usar el método ips
$ipAddresses = $request->ips();
ℹ️ En general la dirección ip debería ser considera no confiable, un input manejado por el usuario que debe ser usado solo con fines informativos.
Content Negotiation
Laravel provee metodos para inspeccionar el content-type aceptado por la request en el encabezado Accept , el método getAcceptableContentTypes devolverá un array con todos los content-types aceptados por la request:
$contentTypes = $request->getAcceptableContentTypes();
El método accepts recibe un array con los content-types y devuelve true o false dependiendo de si alguno es aceptado.
if ($request->accepts(['text/html', 'application/json'])) {
// ...
}
Puedes usar el método prefers para determinar que content-type de un array de content-types es el más preferido por la request, si ninguno de los incluidos es aceptado, se devuelve null
$preferred = $request->prefers(['text/html', 'application/json']);
Puedes usar expectsJson para determinar rápidamente si la request entrante espera una respuesta JSON
if ($request->expectsJson()) {
// ...
}
PSR-7 Requests
El estándar PSR-7 standard especifica interfaces para los mensajes HTTP, incluyendo request y responses. Si necesitas obtener una instancia de una request PSR-7 en vez de una request Laravel, primero necesitarás instalar algunas librerías. Laravel usa el componente Symfony HTTP Message Bridge para convertir una request típica de Laravel o una response en una implementación PSR-7 compatible.
composer require symfony/psr-http-message-bridge
composer require nyholm/psr7
Una vez instaladas estas librerías, podrás obtener una request PSR-7 indicando la interfaz PSR-7 en la ruta o el controlador.
use Psr\Http\Message\ServerRequestInterface;
Route::get('/', function (ServerRequestInterface $request) {
// ...
});
ℹ️ Si devuelves una instancia de Response PSR-7 desde una ruta o controlador, se convertirá automáticamente de vuelta en una instancia de Laravel Response y será mostrada por el framework.
Input
Retrieving Input
Retrieving All Input Data
Puedes devolver toda la información del input (información entrante) como un array usando all , este método puede ser usado sin importar si la request entrante es desde un formulario de HTML o una request XHR
$input = $request->all();
Usando el método collect puedes recuperar lo mismo pero como una collection:
$input = $request->collect();
El método collect permite incluso recolectar solo una porción del input como una collection
$request->collect('users')->each(function (string $user) {
// ...
});
Retrieving an Input Value
Usando simples métodos de Illuminate\Http\Request puedes obtener el input del usuario sin tener en cuenta el HTTP verb:
$name = $request->input('name');
$name = $request->input('name', 'Sally');
// valor por defecto
Cuando trabes con forms que contienen un array de inputs, usa la notación del . para acceder al array
$name = $request->input('products.0.name');
$names = $request->input('products.*.name');
Puedes usar el método input sin parámetros para devolver todo el input como un array asociativo:
$input = $request->input();
Retrieving Input From the Query String
Mientras que el método input devuelve todos los valores del payload (incluyendo los query params), el método query solo devolverá los query params
$name = $request->query('name');
$name = $request->query('name', 'Helen');
// valor por defecto
$query = $request->query();
// toda la información como array asociativo
Retrieving JSON Input Values
Cuando se mandos request con JSON, puedes acceder a la información del JSON con el método input si hay un encabezado Content-Type definido como application/json . Usar la notación del . para recuperar valores:
$name = $request->input('user.name');
Retrieving Stringable Input Values
En vez de recuperar algún valor como string , puedes recuperarlo como una instancia de Illuminate\Support\Stringable
Retrieving Integer Input Values
Usando el método integer te permite castear castear el valor del input a un entero, Si el input no esta presente o el cast falla, devolverá el valor que especifiques. Esto es especialmente útil para input de tipo paginación
$perPage = $request->integer('per_page');
Retrieving Boolean Input Values
El método boolean devuelve true para 1,”1”,”true”, “on”,”yes” , cualquier otro false
$archived = $request->boolean('archived');
Retrieving Date Input Values
El método date devuelve una instancia Carbon , si el campo no esta presente, devuelve null
$birthday = $request->date('birthday');
$elapsed = $request->date('elapsed', '!H:i', 'Europe/Madrid');
// 2º format
// 3º timezone
Si el valor esta presente pero tiene un formato incorrecto, se lanzará InvalidArgumentException , es recomendable que valides el campo antes de llamar a date
Retrieving Enum Input Values
Obtener un valor como un enum, si el enum no tiene un case con dicho valor o un backed value, se devolverá null
use App\Enums\Status;
$status = $request->enum('status', Status::class);
Retrieving Input via Dynamic Properties
Puedes acceder a propiedades de la instancia Illuminate\Http\Request usando propiedades dinamicas. Por ejemplo si la request tiene un campo name
$name = $request->name;
Primero Laravel mirara los valores del payload y si no está presente mirara en los query params
Retrieving a Portion of the Input Data
Si solo necesitas recuperar una porción del input, puedes usar only y except , ambos argumentos reciben un array:
$input = $request->only(['username', 'password']);
$input = $request->only('username', 'password');
$input = $request->except(['credit_card']);
$input = $request->except('credit_card');
Input Presence
Puedes usar el método has para determinar si un valor esta presente en la request.
if ($request->has('name')) {
// ...
}
Cuando se le pasa un array determina si todos los valores estan presentes:
if ($request->has(['name', 'email'])) {
// ...
}
El método hasAny devuelve true si alguno de los valores está presente
if ($request->hasAny(['name', 'email'])) {
// ...
}
El método whenHas ejecuta una closure cuando hay un valor presente:
$request->whenHas('name', function (string $input) {
// ...
});
Se puede pasar un segundo closure que se ejecutará si el valor no está presente:
$request->whenHas('name', function (string $input) {
// The "name" value is present...
}, function () {
// The "name" value is not present...
});
Para determinar que un valor esta presente y no es una cadena vacía, usar filled
if ($request->filled('name')) {
// ...
}
Si desea determinar si falta un valor o es una cadena vacia:
if ($request->isNotFilled(['name', 'email'])) {
// ...
}
if ($request->isNotFilled(['name', 'email'])) {
// ...
} // determina si todos los valores faltan
El método anyFilled determina si alguno de los valores especificados esta presente, devolviendo true si alguno lo está
if ($request->anyFilled(['name', 'email'])) {
// ...
}
El **whenFilled**método ejecutará el closure si hay un valor presente en la solicitud y no es una cadena vacía:
$request->whenFilled('name', function (string $input) {
// ...
});
Se puede pasar un segundo closure a whenFilled que se ejecutará si el valor especificado no está “filled”(No presente o cadena vacía):
$request->whenFilled('name', function (string $input) {
// The "name" value is filled...
}, function () {
// The "name" value is not filled...
});
Para determinar si una clave determinada está ausente en la solicitud, puede utilizar los métodos **missing**y whenMissing:
if ($request->missing('name')) {
// ...
}
$request->whenMissing('name', function () {
// The "name" value is missing...
}, function () {
// The "name" value is present...
});
Merging Additional Input
Aveces es necesario incluir en la request input data adicional que quieres, para ello puedes usar el método merge , si alguna clave ya existe, sera sobreescrita por el valor actual:
$request->merge(['votes' => 0]);
Con mergeIfMissing puedes mergear solamente si la clave no existe previamente:
$request->mergeIfMissing(['votes' => 0]);
Old Input
Laravel te permite mantener inputs de una request durante la siguiente request. Esta funcionalidad es particularmente útil para re-popular formularios después de detectar un error de validación. Sin embargo, si estás usando la funcionalidad de validación de laravel (validation features), es posible que no necesites manualmente flashear (guardar datos solamente para la siguiente request) usando estos métodos dado que las validaciones integradas en laravel las llamará automáticamente
Flashing Input to the Session
El método flash guardará el input de la actual request para la siguiente request
$request->flash();
Puedes usar flashOnly y flashExcept para flasear una porción de la información de la request actual. Estos métodos son útiles para guardar passwords y información sensible
Flashing Input Then Redirecting
Dado que es frecuente redireccionar flasheando la información actual puedes usar withInput:
return redirect('/form')->withInput();
return redirect()->route('user.create')->withInput();
return redirect('/form')->withInput(
$request->except('password')
);
Retrieving Old Input
Para obtener información flasheada de la request previa, usa el método old en una instancia de
Illuminate\Http\Request . El método old devolverá la data previamente flasheada desde la session
$username = $request->old('username');
Laravel tambien provee una función global old para para usarlo en los Blade templates
<input type="text" name="username" value="{{ old('username') }}">
Cookies
Retrieving Cookies From Requests
Todas las cookies creadas por Laravel estan encriptadas y firmadas con un código de authenticación, lo que signfica que sera considerada invalida si es cambiada por el cliente. Para recuperar una cookie usar el método cookiede Illuminate\Http\Request
$value = $request->cookie('name');
Input Trimming and Normalization
Por defecto laravel incluye los middleware Illuminate\Foundation\Http\Middleware\TrimStrings y Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull en los middleware globales de tu aplicación. Estos middleware automáticamente quitaran los espacios de los strings y convertirán cualquier cadena vacía en un null. Por lo que no tienes que realizar esta normalización en tus rutas o controladores
Disabling Input Normalization
Si quieres borrar estos middlewares:
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
use Illuminate\Foundation\Http\Middleware\TrimStrings;
->withMiddleware(function (Middleware $middleware) {
$middleware->remove([
ConvertEmptyStringsToNull::class,
TrimStrings::class,
]);
})
Si quieres quitar estos middlewares para un grupo de request puedes hacerlo de esta forma:
->withMiddleware(function (Middleware $middleware) {
$middleware->convertEmptyStringsToNull(except: [
fn (Request $request) => $request->is('admin/*'),
]);
$middleware->trimStrings(except: [
fn (Request $request) => $request->is('admin/*'),
]);
})
Files
Retrieving Uploaded Files
Puedes recuperar archivos subidos en la instancia de Illuminate\Http\Request usando el método file o accediendo como propiedad dinamica. El método file devolverá una instancia de Illuminate\Http\UploadedFile el cual extiende de la clase de php SplFileInfo y provee de una variedad de metodos para interactuar con el file
$file = $request->file('photo');
$file = $request->photo;
Para determinar si un file está presente, usar hasFile
if ($request->hasFile('photo')) {
// ...
}
Validating Successful Uploads
Aparte de comprobar que el file esta presente, puedes comprobar que no ha habido problemas subiendo el archivo con el método isValid
if ($request->file('photo')->isValid()) {
// ...
}
File Paths and Extensions
La clase UploadedFile contiene métodos para acceder al path y la extensión del file. El método intentará averiguar la extensión del archivo basado en su contenido. Esta extensión puede ser diferente de la extension que fue suministrada por el cliente
$path = $request->photo->path();
$extension = $request->photo->extension();
Other File Methods
Para mas metodos con files, ver https://github.com/symfony/symfony/blob/6.0/src/Symfony/Component/HttpFoundation/File/UploadedFile.php
Storing Uploaded Files
Para guardar un file subido, típicamente usarás alguno de tus filesystems configurados.
La clase UploadedFile tiene un método store que moverá to file subido a alguno de tus discos, el cual puede ser en tu sistema de archivos local o en almacenamiento en la nube como Amazon S3.
El método store acepta un path donde el file sera guardado relativo al directorio root del filesystem configurado. Este path no deberá contener un nombre de archivo, dado que un unique ID sera generado para servir como nombre del archivo.
El metodo storetambien acepta un segundo parametro opcional con el nombre del disco que debera ser usado para guardar el file. Este método devolvera el path del file relativo al root del disco:
$path = $request->photo->store('images');
$path = $request->photo->store('images', 's3');
Si no quieres que se genera automáticamente un nombre para el archivo, deberás usar storeAs
el cual acepta el path, filename, y disk como argumentos
$path = $request->photo->storeAs('images', 'filename.jpg');
$path = $request->photo->storeAs('images', 'filename.jpg', 's3');
ℹ️ Para más información acerca del guardado de files en Laravel, mirar file storage documentation.
Configuring Trusted Proxies
Cuando corres tu aplicación detrás de un load balance que termina los certificados TLS / SSL,
puedes darte cuenta que tu aplicación aveces no genera los links HTTPS cuando usas el helper url . Normalmente esto es porque tu aplicación recibe tráfico desde tu load balance en el puerto 80 y no sabe que tiene que generar links seguros.
Para arreglar esto, deberas activar el middleware Illuminate\Http\Middleware\TrustProxies que esta incluido en la aplicación Laravel, el cual te permite rapidamente customizar que load balancers o proxies deben ser confiables para tu aplicación. Tus trusted proxies deberán estar especificados en el middleware trustProxies dentro del archivo bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(at: [
'192.168.1.1',
'10.0.0.0/8',
]);
})
Además para configurar tus trusted proxies, deberás configurar los proxy headers que deben ser confiables
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(headers: Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB
);
})
ℹ️ ℹ️ Si estás usando AWS Elastic Load Balancing, el valor de los encabezados debe ser Request::HEADER_X_FORWARDED_AWS_ELB. Si tu balanceador de carga utiliza el encabezado estándar Forwarded de la RFC 7239, el valor de los encabezados debe ser Request::HEADER_FORWARDED. Para más información sobre las constantes que pueden usarse en el valor de los encabezados, consulta la documentación de Symfony sobre los trusted proxies en proxies en trusting proxies.
Trusting All Proxies
Si estas usando Amazon AWS o otro load balancer de la nube, puedes no saber la dirección ip de tu actual balanceador. En estos casos puedes usar * para confiar en todos los proxies
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(at: '*');
})
Configuring Trusted Hosts
Por defecto Laravel respondera a todas las request que recipa indiferentemente del encabezado Host de la request HTTP. Además, el encabezadoHost sera usado cuando se genere URLS absolutas a tu aplicación durante una petición web.
Normalmente, deberás configurar tu servidor web, como Nginx o Apache para solamente enviar request a tu aplicación las cuales coincidan con un hostname dado. Sin embargo, si no tienes la habilidad para customizar tu web server directamente y necesitas instruir a Laravel de que solo responda a ciertos hostnames, puedes hacerlo activando el middleware Illuminate\Http\Middleware\TrustHosts de tu aplicación.
Para activar el middleware deberas invocarlo en el archivo bootstrap/app.php , Usando el argumento at puedes especificar los hostnames a los que tu aplicación debe responder. Las peticiones con otro encabezados Host diferente serán rechazadas.
->withMiddleware(function (Middleware $middleware) {
$middleware->trustHosts(at: ['laravel.test']);
})
Por defecto, las peticiones que viene de subdominios de la URL de la aplicación son automáticamente confiables. Si deseas desactivar este comportamiento, deberás usar el argumento subdomains
->withMiddleware(function (Middleware $middleware) {
$middleware->trustHosts(at: ['laravel.test'], subdomains: false);
})
Si necesidas acceder a los archivos de configuración de tu aplicación o a la base de datos para determinar los trusted host, puedes proporcionar una función para el metodo at
->withMiddleware(function (Middleware $middleware) {
$middleware->trustHosts(at: fn () => config('app.trusted_hosts'));
})