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'));
})