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

# Génération d'URL

> Comment utiliser le helper url() de Laravel, générer des URLs vers des routes nommées, des URLs signées et des URLs d'action de contrôleur.

## Introduction

Laravel propose plusieurs helpers pour générer les URL de votre application.
Ils sont particulièrement utiles pour construire des liens dans les templates ou les réponses d'API, ou pour générer des réponses de redirection.

## Utilisation de base

### Générer une URL

Le helper `url` permet de générer n'importe quelle URL.
L'URL générée utilise automatiquement le schéma (HTTP ou HTTPS) et l'hôte de la requête en cours.

```php theme={null}
$post = App\Models\Post::find(1);

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

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

Pour générer une URL avec une chaîne de requête, utilisez la méthode `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
```

Si vous spécifiez un paramètre de requête déjà présent dans le chemin, la valeur existante est écrasée.

```php theme={null}
echo url()->query('/posts?sort=latest', ['sort' => 'oldest']);

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

Vous pouvez aussi passer des tableaux comme valeurs de paramètres. Ils seront correctement indexés et encodés dans l'URL générée.

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

### Récupérer l'URL courante

Sans chemin, `url` renvoie une instance de `Illuminate\Routing\UrlGenerator` donnant accès à l'URL courante.

```php theme={null}
// URL actuelle sans la chaîne de requête
echo url()->current();

// URL actuelle avec la chaîne de requête
echo url()->full();
```

Ces méthodes sont aussi accessibles via la [façade](./facades) `URL`.

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

echo URL::current();
```

### Récupérer l'URL précédente

Vous voulez parfois connaître l'URL précédemment visitée par l'utilisateur. Utilisez `previous` ou `previousPath` du helper `url`.

```php theme={null}
// URL complète de la requête précédente
echo url()->previous();

// Chemin de la requête précédente
echo url()->previousPath();
```

Vous pouvez aussi la récupérer via la session.

```php theme={null}
use Illuminate\Http\Request;

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

    // ...
});
```

Il est également possible d'obtenir le nom de la route précédente via la session.

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

## URL vers des routes nommées

Le helper `route` permet de générer une URL vers une [route nommée](./routing#named-routes).
Les routes nommées évitent de dépendre de l'URL réelle définie sur la route.
Ainsi, si l'URL change, il n'y a pas besoin de modifier les appels à `route`.

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

Générez une URL vers cette route ainsi :

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

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

Les routes à plusieurs paramètres sont également gérées.

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

Les éléments de tableau supplémentaires qui ne correspondent pas aux paramètres définis sont ajoutés à la chaîne de requête.

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

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

### Modèles Eloquent

Souvent, vous générez des URL avec la clé de route d'un modèle Eloquent (généralement la clé primaire).
Passez le modèle directement comme valeur de paramètre ; `route` extrait automatiquement la clé de route du modèle.

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

### URL signées

Laravel permet de créer facilement des URL « signées » vers des routes nommées.
Un hachage de « signature » est ajouté à la chaîne de requête, ce qui permet à Laravel de vérifier qu'elle n'a pas été altérée.
Les URL signées sont particulièrement utiles pour des routes accessibles publiquement mais qui doivent être protégées contre la manipulation.

Par exemple, on peut les utiliser pour un lien public de « désinscription » envoyé par e-mail.
Utilisez la méthode `signedRoute` de la façade `URL`.

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

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

Avec l'argument `absolute` de `signedRoute`, on peut exclure le domaine du hachage de signature.

```php theme={null}
return URL::signedRoute('unsubscribe', ['user' => 1], absolute: false);
```

Pour une URL signée temporaire, expirant après un certain temps, utilisez `temporarySignedRoute`.
Laravel vérifie alors que l'horodatage d'expiration encodé n'est pas dépassé.

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

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

#### Flux de vérification d'une URL signée

```mermaid theme={null}
sequenceDiagram
    participant App as Application Laravel
    participant User as Utilisateur
    participant Mail as E-mail
    App->>App: URL::signedRoute() / temporarySignedRoute()
    App->>Mail: Envoi de l'URL signée par e-mail
    Mail->>User: Réception de l'e-mail
    User->>App: Clic sur l'URL (requête GET)
    App->>App: Vérification de la signature<br>hasValidSignature()
    alt Signature valide
        App->>User: Traitement exécuté (ex. : désinscription)
    else Signature invalide/expirée
        App->>User: Erreur 403
    end
```

#### Vérifier une requête de route signée

Pour vérifier que la requête reçue possède une signature valide, appelez `hasValidSignature` sur l'instance `Illuminate\Http\Request`.

```php theme={null}
use Illuminate\Http\Request;

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

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

Pour ignorer certains paramètres de requête pendant la vérification, utilisez `hasValidSignatureWhileIgnoring`.

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

Vous pouvez aussi affecter le [middleware](./middleware) `signed` (`Illuminate\Routing\Middleware\ValidateSignature`) à la route au lieu d'utiliser l'instance de requête.
Si la signature est invalide, le middleware retourne automatiquement une réponse HTTP `403`.

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

Si l'URL signée n'inclut pas le domaine, spécifiez l'argument `relative` au middleware.

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

#### Réponse aux URL signées invalides

Une URL signée expirée affiche par défaut une page d'erreur générique avec le code HTTP `403`.
Personnalisez ce comportement en définissant une closure `render` pour l'exception `InvalidSignatureException` dans `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 d'action de contrôleur

La fonction `action` génère une URL vers une action de contrôleur.

```php theme={null}
use App\Http\Controllers\HomeController;

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

Si la méthode reçoit des paramètres de route, passez un tableau associatif en deuxième argument.

```php theme={null}
$url = action([UserController::class, 'profile'], ['id' => 1]);
```

## Objet URI fluent

La classe URI de Laravel offre une interface fluent pratique pour créer et manipuler des URI en tant qu'objets.

```php theme={null}
use App\Http\Controllers\UserController;
use Illuminate\Support\Uri;

// Crée une instance URI depuis une chaîne
$uri = Uri::of('https://example.com/path');

// Vers un chemin, une route nommée, une action de contrôleur
$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']);

// Depuis l'URL de la requête courante
$uri = $request->uri();
```

Une fois l'instance URI récupérée, modifiez-la de manière fluent.

```php theme={null}
$uri = Uri::of('https://example.com')
    ->withScheme('http')
    ->withHost('test.com')
    ->withPort(8000)
    ->withPath('/users')
    ->withQuery(['page' => 2])
    ->withFragment('section-1');
```

## Paramètres URL par défaut

Vous voulez parfois définir des valeurs par défaut pour toute la requête.
Par exemple, si de nombreuses routes ont un paramètre `{locale}` :

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

Passer `locale` à chaque appel de `route` est pénible.
Utilisez `URL::defaults` pour définir une valeur par défaut appliquée durant la requête.
Appelez-la depuis un [middleware de route](./middleware#assigning-middleware-to-routes) pour accéder à la requête.

```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
{
    /**
     * Traite la requête 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);
    }
}
```

Une fois la valeur par défaut de `locale` définie, plus besoin de la passer à `route`.

<Info>
  La définition de valeurs par défaut peut interférer avec l'implicit model binding de Laravel.
  Configurez la [priorité des middlewares](./middleware#sorting-middleware) pour que le middleware définissant les valeurs par défaut s'exécute avant `SubstituteBindings` de Laravel.
  Utilisez la méthode `priority` dans `bootstrap/app.php`.

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

- [Routage](/fr/routing.md)
- [Remote Sessions](/fr/packages/laravel-copilot-sdk/remote-sessions.md)
- [Laravel AI SDK](/fr/ai-sdk.md)
- [Guide de développement d'applications intégrées à l'API du moteur - VOICEVOX for Laravel](/fr/packages/laravel-voicevox/app-guide.md)
- [Les nouveautés de Laravel 13](/fr/blog/laravel-13-new-features.md)
