> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Generazione degli URL

> Spiega l'helper url(), l'URL delle route con nome, gli URL firmati e la generazione di URL per le action dei controller in Laravel.

## 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.

```php theme={null}
$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`.

```php theme={null}
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.

```php theme={null}
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.

```php theme={null}
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.

```php theme={null}
// 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](./facades) `URL`.

```php theme={null}
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`.

```php theme={null}
// URL completo della richiesta precedente
echo url()->previous();

// Path della richiesta precedente
echo url()->previousPath();
```

Puoi ottenere l'URL precedente anche tramite la sessione.

```php theme={null}
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.

```php theme={null}
$previousRoute = $request->session()->previousRoute();
```

## URL delle route con nome

L'helper `route` può essere usato per generare URL verso [route con nome](./routing#named-routes).
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`.

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

Per generare l'URL di questa route:

```php theme={null}
echo route('post.show', ['post' => 1]);

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

Sono supportate anche route con più parametri.

```php theme={null}
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.

```php theme={null}
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.

```php theme={null}
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.

```php theme={null}
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.

```php theme={null}
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.

```php theme={null}
use Illuminate\Support\Facades\URL;

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

#### Flusso di verifica di un URL firmato

```mermaid theme={null}
sequenceDiagram
    participant App as App Laravel
    participant User as Utente
    participant Mail as Email
    App->>App: URL::signedRoute() / temporarySignedRoute()
    App->>Mail: Invia l'URL firmato per email
    Mail->>User: Ricezione dell'email
    User->>App: Clicca sull'URL (richiesta GET)
    App->>App: Verifica della firma<br>hasValidSignature()
    alt Firma valida
        App->>User: Esegue l'operazione (es. disiscrizione)
    else Firma non valida o scaduta
        App->>User: Errore 403
    end
```

#### 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`.

```php theme={null}
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`.

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

In alternativa alla richiesta in arrivo, puoi assegnare alla route il [middleware](./middleware) `signed` (`Illuminate\Routing\Middleware\ValidateSignature`).
Se la richiesta non ha una firma valida, il middleware restituisce automaticamente una risposta HTTP `403`.

```php theme={null}
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.

```php theme={null}
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`.

```php theme={null}
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.

```php theme={null}
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.

```php theme={null}
$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.

```php theme={null}
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.

```php theme={null}
$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.

```php theme={null}
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](./middleware#assigning-middleware-to-routes) puoi accedere alla richiesta corrente.

```php theme={null}
<?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`.

<Info>
  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](./middleware#sorting-middleware).
  Puoi configurarlo in `bootstrap/app.php` usando il metodo `priority`.

  ```php theme={null}
  ->withMiddleware(function (Middleware $middleware): void {
      $middleware->prependToPriorityList(
          before: \Illuminate\Routing\Middleware\SubstituteBindings::class,
          prepend: \App\Http\Middleware\SetDefaultLocaleForUrls::class,
      );
  })
  ```
</Info>


## Related topics

- [Routing](/it/routing.md)
- [Gestione degli errori](/it/error-handling.md)
- [Guida allo sviluppo di app con l'API del motore - VOICEVOX for Laravel](/it/packages/laravel-voicevox/app-guide.md)
- [RPC (Remote Procedure Call)](/it/packages/laravel-copilot-sdk/rpc.md)
- [Remote Sessions](/it/packages/laravel-copilot-sdk/remote-sessions.md)
