Vai al contenuto principale

Introduzione

Laravel fornisce diversi helper per generare gli URL dell’applicazione. Sono particolarmente utili per costruire link nei template e nelle risposte API, o per generare risposte di redirect verso un altro punto dell’applicazione.

Uso di base

Generazione di un URL

Con l’helper url puoi generare un URL qualsiasi. L’URL generato usa automaticamente schema (HTTP o HTTPS) e host della richiesta corrente in elaborazione.
$post = App\Models\Post::find(1);

echo url("/posts/{$post->id}");

// http://example.com/posts/1
Per generare un URL con parametri di query usa il metodo query.
echo url()->query('/posts', ['search' => 'Laravel']);

// https://example.com/posts?search=Laravel

echo url()->query('/posts?sort=latest', ['search' => 'Laravel']);

// http://example.com/posts?sort=latest&search=Laravel
Se specifichi un parametro di query già presente nel path, il valore esistente viene sovrascritto.
echo url()->query('/posts?sort=latest', ['sort' => 'oldest']);

// http://example.com/posts?sort=oldest
Puoi passare come parametro anche un array. I valori vengono correttamente indicizzati e codificati nell’URL generato.
echo $url = url()->query('/posts', ['columns' => ['title', 'body']]);

// http://example.com/posts?columns%5B0%5D=title&columns%5B1%5D=body

echo urldecode($url);

// http://example.com/posts?columns[0]=title&columns[1]=body

Ottenere l’URL corrente

Se non passi un path all’helper url, viene restituita un’istanza di Illuminate\Routing\UrlGenerator che ti permette di accedere alle informazioni sull’URL corrente.
// URL corrente senza query string
echo url()->current();

// URL corrente con query string
echo url()->full();
Puoi accedere a questi metodi anche tramite la facade URL.
use Illuminate\Support\Facades\URL;

echo URL::current();

Ottenere l’URL precedente

A volte vuoi conoscere l’URL visitato appena prima. Puoi recuperarlo con i metodi previous e previousPath dell’helper url.
// URL completo della richiesta precedente
echo url()->previous();

// Path della richiesta precedente
echo url()->previousPath();
Puoi ottenere l’URL precedente anche tramite la sessione.
use Illuminate\Http\Request;

Route::post('/users', function (Request $request) {
    $previousUri = $request->session()->previousUri();

    // ...
});
Puoi anche ottenere via sessione il nome della route dell’URL precedentemente visitato.
$previousRoute = $request->session()->previousRoute();

URL delle route con nome

L’helper route può essere usato per generare URL verso route con nome. Con le route con nome, la generazione degli URL non dipende dall’URL effettivo definito nella route. Se l’URL della route cambia, non devi modificare le chiamate a route.
Route::get('/post/{post}', function (Post $post) {
    // ...
})->name('post.show');
Per generare l’URL di questa route:
echo route('post.show', ['post' => 1]);

// http://example.com/post/1
Sono supportate anche route con più parametri.
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
Gli elementi aggiuntivi dell’array che non corrispondono a parametri di route definiti vengono aggiunti come query string.
echo route('post.show', ['post' => 1, 'search' => 'rocket']);

// http://example.com/post/1?search=rocket

Modelli Eloquent

Spesso userai la route key (di norma la chiave primaria) dei modelli Eloquent per generare gli URL. Per farlo puoi passare direttamente il modello come valore del parametro: l’helper route estrae automaticamente la route key.
echo route('post.show', ['post' => $post]);

URL firmati

Laravel semplifica la creazione di URL “firmati” verso route con nome. Alle query string di questi URL viene aggiunto un hash “firmato” che Laravel usa per verificare che l’URL non sia stato manomesso dopo la creazione. Gli URL firmati sono particolarmente utili per route pubbliche che devono comunque essere protette dalla manipolazione. Ad esempio, puoi usare URL firmati per implementare un link pubblico di “disiscrizione” inviato per email ai clienti. Con il metodo signedRoute della facade URL crei un URL firmato.
use Illuminate\Support\Facades\URL;

return URL::signedRoute('unsubscribe', ['user' => 1]);
Specificando l’argomento absolute in signedRoute puoi escludere il dominio dall’hash della firma.
return URL::signedRoute('unsubscribe', ['user' => 1], absolute: false);
Per generare un URL firmato temporaneo che scade dopo un tempo indicato usa temporarySignedRoute. Nella verifica di un URL firmato temporaneo, Laravel controlla che il timestamp di scadenza codificato nell’URL non sia stato superato.
use Illuminate\Support\Facades\URL;

return URL::temporarySignedRoute(
    'unsubscribe', now()->plus(minutes: 30), ['user' => 1]
);

Flusso di verifica di un URL firmato

Verifica delle richieste alle route firmate

Per verificare che la richiesta in arrivo abbia una firma valida chiama il metodo hasValidSignature dell’istanza Illuminate\Http\Request.
use Illuminate\Http\Request;

Route::get('/unsubscribe/{user}', function (Request $request) {
    if (! $request->hasValidSignature()) {
        abort(401);
    }

    // ...
})->name('unsubscribe');
Per ignorare alcuni parametri di query nella verifica usa hasValidSignatureWhileIgnoring.
if (! $request->hasValidSignatureWhileIgnoring(['page', 'order'])) {
    abort(401);
}
In alternativa alla richiesta in arrivo, puoi assegnare alla route il middleware signed (Illuminate\Routing\Middleware\ValidateSignature). Se la richiesta non ha una firma valida, il middleware restituisce automaticamente una risposta HTTP 403.
Route::post('/unsubscribe/{user}', function (Request $request) {
    // ...
})->name('unsubscribe')->middleware('signed');
Se l’URL firmato non contiene il dominio, passa l’argomento relative al middleware.
Route::post('/unsubscribe/{user}', function (Request $request) {
    // ...
})->name('unsubscribe')->middleware('signed:relative');

Risposta agli URL firmati non validi

Accedendo a un URL firmato scaduto viene mostrata la pagina di errore generica con status HTTP 403. Puoi personalizzare questo comportamento definendo una closure di rendering personalizzata per l’eccezione InvalidSignatureException in bootstrap/app.php.
use Illuminate\Routing\Exceptions\InvalidSignatureException;

->withExceptions(function (Exceptions $exceptions): void {
    $exceptions->render(function (InvalidSignatureException $e) {
        return response()->view('errors.link-expired', status: 403);
    });
})

URL delle action dei controller

La funzione action genera l’URL per l’action del controller indicato.
use App\Http\Controllers\HomeController;

$url = action([HomeController::class, 'index']);
Se il metodo del controller riceve parametri di route, passa un array associativo dei parametri nel secondo argomento.
$url = action([UserController::class, 'profile'], ['id' => 1]);

Oggetto URI fluido

La classe URI di Laravel offre un’interfaccia fluida per creare e manipolare URI tramite oggetti.
use App\Http\Controllers\UserController;
use Illuminate\Support\Uri;

// Crea un'istanza URI da una stringa
$uri = Uri::of('https://example.com/path');

// Crea URI verso path, route con nome, action del controller
$uri = Uri::to('/dashboard');
$uri = Uri::route('users.show', ['user' => 1]);
$uri = Uri::signedRoute('users.show', ['user' => 1]);
$uri = Uri::temporarySignedRoute('user.index', now()->plus(minutes: 5));
$uri = Uri::action([UserController::class, 'index']);

// Crea un'istanza URI dall'URL della richiesta corrente
$uri = $request->uri();
Ottenuta l’istanza URI, puoi modificarla in modo fluido.
$uri = Uri::of('https://example.com')
    ->withScheme('http')
    ->withHost('test.com')
    ->withPort(8000)
    ->withPath('/users')
    ->withQuery(['page' => 2])
    ->withFragment('section-1');

Parametri URL predefiniti

A volte vuoi impostare valori predefiniti per certi parametri URL a livello di richiesta. Ad esempio, molte route hanno un parametro {locale} definito.
Route::get('/{locale}/posts', function () {
    // ...
})->name('post.index');
Passare locale ogni volta che chiami route è scomodo. Usa il metodo URL::defaults per definire un valore predefinito per questo parametro che venga sempre applicato durante la richiesta corrente. Chiamandolo da un route middleware puoi accedere alla richiesta corrente.
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\URL;
use Symfony\Component\HttpFoundation\Response;

class SetDefaultLocaleForUrls
{
    /**
     * Gestisce una richiesta in ingresso.
     *
     * @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);
    }
}
Con il valore predefinito di locale impostato, non è più necessario passarlo quando generi URL con l’helper route.
L’impostazione dei valori predefiniti degli URL può interferire con l’implicit model binding di Laravel. Fai in modo che il middleware che imposta i valori predefiniti venga eseguito prima del middleware SubstituteBindings di Laravel, tramite l’ordinamento dei middleware. Puoi configurarlo in bootstrap/app.php usando il metodo priority.
->withMiddleware(function (Middleware $middleware): void {
    $middleware->prependToPriorityList(
        before: \Illuminate\Routing\Middleware\SubstituteBindings::class,
        prepend: \App\Http\Middleware\SetDefaultLocaleForUrls::class,
    );
})
Ultima modifica il 13 luglio 2026