Documentación de Laravel 10.x
Aquí encontrarás fragmentos de código de Laravel y consejos útiles sobre desarrollo web.
Laravel proporciona varios ayudantes para ayudarte a generar URL para tu aplicación. Estos ayudantes son especialmente útiles al construir enlaces en tus plantillas y respuestas de API, o al generar respuestas de redirección a otra parte de tu aplicación.
El ayudante url
se puede usar para generar URL arbitrarias para tu aplicación. La URL generada usará automáticamente el esquema (HTTP o HTTPS) y el host de la solicitud actual que está siendo manejada por la aplicación:
$post = App\Models\Post::find(1); echo url("/posts/{$post->id}"); // http://example.com/posts/1
Si no se proporciona ninguna ruta al ayudante url
, se devuelve una instancia de Illuminate\Routing\UrlGenerator
, lo que te permite acceder a la información sobre la URL actual:
// Obtener la URL actual sin la cadena de consulta...echo url()->current(); // Obtener la URL actual incluyendo la cadena de consulta...echo url()->full(); // Obtener la URL completa de la solicitud anterior...echo url()->previous();
Cada uno de estos métodos también se puede acceder mediante el facade URL
:
use Illuminate\Support\Facades\URL; echo URL::current();
El ayudante route
se puede usar para generar URL a rutas con nombre. Las rutas con nombre te permiten generar URL sin estar acoplado a la URL real definida en la ruta. Por lo tanto, si la URL de la ruta cambia, no es necesario realizar cambios en tus llamadas a la función route
. Por ejemplo, imagina que tu aplicación contiene una ruta definida de la siguiente manera:
Route::get('/post/{post}', function (Post $post) { // ...})->name('post.show');
Para generar una URL a esta ruta, puedes usar el ayudante route
de la siguiente manera:
echo route('post.show', ['post' => 1]); // http://example.com/post/1
Por supuesto, el ayudante route
también se puede usar para generar URL para rutas con varios parámetros:
Route::get('/post/{post}/comment/{comment}', function (Post $post, Comment $comment) { // ...})->name('comment.show'); echo route('comment.show', ['post' => 1, 'comment' => 3]); // http://example.com/post/1/comment/3
Cualquier elemento adicional del array que no corresponda a los parámetros de definición de la ruta se agregará a la cadena de consulta de la URL:
echo route('post.show', ['post' => 1, 'search' => 'rocket']); // http://example.com/post/1?search=rocket
A menudo, generarás URL utilizando la clave de ruta (típicamente la clave primaria) de modelos Eloquent. Por esta razón, puedes pasar modelos Eloquent como valores de parámetros. El ayudante route
extraerá automáticamente la clave de ruta del modelo:
echo route('post.show', ['post' => $post]);
Laravel te permite crear fácilmente URLs "firmadas" para rutas con nombre. Estas URLs tienen un hash de "firma" agregado a la cadena de consulta que permite a Laravel verificar que la URL no ha sido modificada desde que se creó. Las URLs firmadas son especialmente útiles para rutas que son accesibles públicamente pero necesitan una capa de protección contra la manipulación de URL.
Por ejemplo, podrías usar URLs firmadas para implementar un enlace público "darse de baja" que se envía por correo electrónico a tus clientes. Para crear una URL firmada a una ruta con nombre, usa el método signedRoute
del facade URL
:
use Illuminate\Support\Facades\URL; return URL::signedRoute('unsubscribe', ['user' => 1]);
Puedes excluir el dominio del hash de la URL firmada proporcionando el argumento absolute
al método signedRoute
:
return URL::signedRoute('unsubscribe', ['user' => 1], absolute: false);
Si deseas generar una URL de ruta firmada temporal que caduque después de un tiempo especificado, puedes usar el método temporarySignedRoute
. Cuando Laravel valida una URL de ruta temporal firmada, se asegurará de que la marca de tiempo de vencimiento codificada en la URL firmada no haya transcurrido:
use Illuminate\Support\Facades\URL; return URL::temporarySignedRoute( 'unsubscribe', now()->addMinutes(30), ['user' => 1]);
Para verificar que una solicitud entrante tiene una firma válida, debes llamar al método hasValidSignature
en la instancia entrante de Illuminate\Http\Request
:
use Illuminate\Http\Request; Route::get('/unsubscribe/{user}', function (Request $request) { if (! $request->hasValidSignature()) { abort(401); } // ...})->name('unsubscribe');
A veces, es posible que necesites permitir que el frontend de tu aplicación agregue datos a una URL firmada, como al realizar paginación del lado del cliente. Por lo tanto, puedes especificar los parámetros de consulta de la solicitud que deben ignorarse al validar una URL firmada mediante el método hasValidSignatureWhileIgnoring
. Recuerda, ignorar parámetros permite a cualquiera modificar esos parámetros en la solicitud:
if (! $request->hasValidSignatureWhileIgnoring(['page', 'order'])) { abort(401);}
En lugar de validar las URL firmadas mediante la instancia entrante de la solicitud, puedes asignar el middleware Illuminate\Routing\Middleware\ValidateSignature
a la ruta. Si aún no está presente, puedes asignarle un alias a este middleware en el array $middlewareAliases
de tu kernel HTTP:
/** * Los alias de middleware de la aplicación. * * Los alias se pueden usar para asignar middleware convenientemente a rutas y grupos. * * @var array<string, class-string|string> */protected $middlewareAliases = [ 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,];
Una vez que hayas registrado el middleware en tu kernel, puedes adjuntarlo a una ruta. Si la solicitud entrante no tiene una firma válida, el middleware devolverá automáticamente una respuesta HTTP 403
:
Route::post('/unsubscribe/{user}', function (Request $request) { // ...})->name('unsubscribe')->middleware('signed');
Si tus URL firmadas no incluyen el dominio en el hash de la URL, debes proporcionar el argumento relative
al middleware:
Route::post('/unsubscribe/{user}', function (Request $request) { // ...})->name('unsubscribe')->middleware('signed:relative');
Cuando alguien visita una URL firmada que ha caducado, recibirá una página de error genérica para el código de estado HTTP 403
. Sin embargo, puedes personalizar este comportamiento definiendo un cierre de "renderizable" personalizado para la excepción InvalidSignatureException
en tu manejador de excepciones. Este cierre debería devolver una respuesta HTTP:
use Illuminate\Routing\Exceptions\InvalidSignatureException; /** * Registra las devoluciones de llamada para el manejo de excepciones en la aplicación. */public function register(): void{ $this->renderable(function (InvalidSignatureException $e) { return response()->view('error.link-expired', [], 403); });}
La función action
genera una URL para la acción de controlador dada:
use App\Http\Controllers\HomeController; $url = action([HomeController::class, 'index']);
Si el método del controlador acepta parámetros de ruta, puedes pasar un array asociativo de parámetros de ruta como segundo argumento a la función:
$url = action([UserController::class, 'profile'], ['id' => 1]);
Para algunas aplicaciones, es posible que desees especificar valores predeterminados para ciertos parámetros de URL en toda la solicitud. Por ejemplo, imagina que muchas de tus rutas definen un parámetro {locale}
:
Route::get('/{locale}/posts', function () { // ...})->name('post.index');
Es engorroso tener que pasar siempre el locale
cada vez que llamas al ayudante route
. Entonces, puedes usar el método URL::defaults
para definir un valor predeterminado para este parámetro que siempre se aplicará durante la solicitud actual. Puedes llamar a este método desde un middleware de ruta para tener acceso a la solicitud actual:
<?php namespace App\Http\Middleware; use Closure;use Illuminate\Http\Request;use Illuminate\Support\Facades\URL;use Symfony\Component\HttpFoundation\Response; class SetDefaultLocaleForUrls{ /** * Maneja una solicitud entrante. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next): Response { URL::defaults(['locale' => $request->user()->locale]); return $next($request); }}
Una vez que se ha establecido el valor predeterminado para el parámetro locale
, ya no es necesario pasar su valor al generar URL mediante el ayudante route
.
Establecer valores predeterminados de URL puede interferir con el manejo de las vinculaciones de modelos implícitas de Laravel. Por lo tanto, debes priorizar tu middleware que establece valores predeterminados de URL para que se ejecute antes del propio middleware SubstituteBindings
de Laravel. Puedes lograr esto asegurándote de que tu middleware ocurra antes del middleware SubstituteBindings
dentro de la propiedad $middlewarePriority
del kernel HTTP de tu aplicación.
La propiedad $middlewarePriority
está definida en la clase base Illuminate\Foundation\Http\Kernel
. Puedes copiar su definición de esa clase y sobrescribirla en el kernel HTTP de tu aplicación para modificarla:
/** * La lista de middleware ordenada por prioridad. * * Esto fuerza a que el middleware no global siempre esté en el orden dado. * * @var array */protected $middlewarePriority = [ // ... \App\Http\Middleware\SetDefaultLocaleForUrls::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, // ...];