URL

Introduzione

Laravel offre diversi helper per aiutarti a generare URL per la tua applicazione. Questi helper sono soprattutto utili quando crei link nei tuoi template e nelle risposte API, oppure quando generi risposte di reindirizzamento verso un’altra parte della tua applicazione.

Nozioni di Base

Generare URL

L’helper url può essere utilizzato per generare URL arbitrarie per la tua applicazione. L’URL generata utilizzerà automaticamente lo schema (HTTP o HTTPS) e l’host dalla richiesta corrente gestita dall’applicazione:

$post = App\Models\Post::find(1);

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

// http://example.com/posts/1

Per generare un URL con parametri nella query string, puoi utilizzare 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

Fornendo parametri della query string già presenti nel percorso sovrascriverai i loro valori esistenti:

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

// http://example.com/posts?sort=oldest

Anche array di valori possono essere passati come parametri della query string. Questi valori saranno correttamente indicizzati e codificati nell’URL generata:

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

Accesso all’URL Corrente

Se non viene fornito un percorso al helper url, viene restituita un’istanza di Illuminate\Routing\UrlGenerator, permettendoti di accedere alle informazioni sull’URL corrente:

// Ottieni l'URL corrente senza la stringa di query...
echo url()->current();

// Ottieni l'URL corrente includendo la stringa di query...
echo url()->full();

// Ottieni l'URL completo per la richiesta precedente...
echo url()->previous();

Ognuno di questi metodi può essere utilizzato anche tramite il URL facade:

use Illuminate\Support\Facades\URL;

echo URL::current();

URL per Rotte Nominate

L’helper route può essere utilizzato per generare URL per rotte nominate. Le rotte nominate permettono di creare URL senza essere vincolati all’URL effettivamente definito nella rotta. Quindi, se l’URL della rotta cambia, non è necessario modificare le chiamate alla funzione route. Ad esempio, immagina che la tua applicazione contenga una rotta definita come segue:

Route::get('/post/{post}', function (Post $post) {
    // ...
})->name('post.show');

Per generare un URL per questa rotta, puoi usare l’helper route in questo modo:

echo route('post.show', ['post' => 1]);

// http://example.com/post/1

Naturalmente, l’helper route può essere utilizzato anche per generare URL per rotte 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

Qualsiasi elemento aggiuntivo nell’array che non corrisponde ai parametri definiti nella rotta verrà aggiunto alla stringa di query dell’URL:

echo route('post.show', ['post' => 1, 'search' => 'rocket']);

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

Modelli Eloquent

Spesso genererai URL usando la route key (tipicamente la primary key) dei modelli Eloquent. Per questo motivo, puoi passare i modelli Eloquent come valori dei parametri. L’helper route estrarrà automaticamente la route key del modello:

echo route('post.show', ['post' => $post]);

URL Firmate

Laravel consente di creare facilmente URL "firmati" per rotte denominate. Questi URL hanno un hash di "firma" aggiunto alla stringa di query, che permette a Laravel di verificare che l’URL non sia stato modificato da quando è stato creato. Gli URL firmati sono particolarmente utili per rotte accessibili pubblicamente ma che necessitano di una protezione contro la manipolazione dell’URL.

Per esempio, potresti usare gli URL firmati per implementare un link pubblico di "disiscrizione" che viene inviato via email ai tuoi clienti. Per creare un URL firmato per una rotta denominata, utilizza il metodo signedRoute della facade URL:

use Illuminate\Support\Facades\URL;

return URL::signedRoute('unsubscribe', ['user' => 1]);

Puoi escludere il dominio dall’hash dell’URL firmato fornendo l’argomento absolute al metodo signedRoute:

return URL::signedRoute('unsubscribe', ['user' => 1], absolute: false);

Se desideri generare un URL firmato temporaneo che scade dopo un determinato periodo, puoi usare il metodo temporarySignedRoute. Quando Laravel convalida un URL di rotta firmata temporanea, assicurerà che il timestamp di scadenza codificato nell’URL firmato non sia trascorso:

use Illuminate\Support\Facades\URL;

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

Validazione delle Richieste di Route Firmate

Per verificare che una richiesta in arrivo abbia una firma valida, devi chiamare il metodo hasValidSignature sull’istanza Illuminate\Http\Request:

use Illuminate\Http\Request;

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

    // ...
})->name('unsubscribe');

A volte, potresti voler permettere al frontend della tua applicazione di aggiungere dati a un URL firmato, ad esempio durante la paginazione lato client. Per questo, puoi specificare i parametri della query che devono essere ignorati durante la validazione di un URL firmato usando il metodo hasValidSignatureWhileIgnoring. Ricorda, ignorare i parametri consente a chiunque di modificarli nella richiesta:

if (! $request->hasValidSignatureWhileIgnoring(['page', 'order'])) {
    abort(401);
}

Invece di validare gli URL firmati usando l’istanza della richiesta, puoi assegnare il middleware signed (Illuminate\Routing\Middleware\ValidateSignature) middleware alla route. Se la richiesta in arrivo non ha una firma valida, il middleware restituirà automaticamente una risposta HTTP 403:

Route::post('/unsubscribe/{user}', function (Request $request) {
    // ...
})->name('unsubscribe')->middleware('signed');

Se i tuoi URL firmati non includono il dominio nell’hash dell’URL, devi fornire l’argomento relative al middleware:

Route::post('/unsubscribe/{user}', function (Request $request) {
    // ...
})->name('unsubscribe')->middleware('signed:relative');

Gestire le Rotte Firmate Non Valide

Quando qualcuno visita un URL firmato che è scaduto, riceverà una pagina di errore generica per lo stato HTTP 403. Puoi però personalizzare questo comportamento definendo una chiusura "render" personalizzata per l’eccezione InvalidSignatureException nel file bootstrap/app.php della tua applicazione:

use Illuminate\Routing\Exceptions\InvalidSignatureException;

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

URL per le Azioni del Controller

La funzione action genera un URL per l’azione del controller specificato:

use App\Http\Controllers\HomeController;

$url = action([HomeController::class, 'index']);

Se il metodo del controller accetta parametri di route, puoi passare un array associativo di parametri di route come secondo argomento della funzione:

$url = action([UserController::class, 'profile'], ['id' => 1]);

Valori Predefiniti

Per alcune applicazioni, potresti voler specificare valori predefiniti a livello di richiesta per certi parametri dell’URL. Ad esempio, immagina che molte delle tue rotte definiscano un parametro {locale}:

    Route::get('/{locale}/posts', function () {
        // ...
    })->name('post.index');

È scomodo dover sempre passare locale ogni volta che chiami l’helper route. Quindi, puoi usare il metodo URL::defaults per definire un valore predefinito per questo parametro che sarà sempre applicato durante la richiesta corrente. Potresti voler chiamare questo metodo da un middleware di rotta in modo da avere accesso alla richiesta attuale:

    <?php

    namespace App\Http\Middleware;

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

    class SetDefaultLocaleForUrls
    {
        /**
         * Gestisci una richiesta in arrivo.
         *
         * @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 volta impostato il valore predefinito per il parametro locale, non è più necessario passare il suo valore quando generi URL tramite l’helper route.

Valori Predefiniti degli URL e Priorità del Middleware

Impostare i valori predefiniti degli URL può interferire con la gestione delle associazioni implicite dei modelli da parte di Laravel. Pertanto, devi dare priorità al tuo middleware che imposta i valori predefiniti degli URL in modo che venga eseguito prima del middleware SubstituteBindings di Laravel. Puoi fare questo utilizzando il metodo priority del middleware nel file bootstrap/app.php della tua applicazione:

->withMiddleware(function (Middleware $middleware) {
    $middleware->prependToPriorityList(
        before: \Illuminate\Routing\Middleware\SubstituteBindings::class,
        prepend: \App\Http\Middleware\SetDefaultLocaleForUrls::class,
    );
})
Lascia un commento

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *