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

# Validation

> Comment utiliser la validation de Laravel pour vérifier les données de formulaire.

## Qu'est-ce que la validation

La validation consiste à vérifier que les données envoyées par un utilisateur satisfont un format et des conditions attendues.
Laravel propose une validation simple et puissante via la méthode `validate` de l'objet de requête ou des form requests dédiés.

```mermaid theme={null}
flowchart TD
    A["Requête HTTP reçue"] --> B["Application des règles"]
    B --> C{{"Validation<br>réussie ?"}}
    C -->|"Succès"| D["Récupération des données validées"]
    D --> E["Exécution de la logique du contrôleur"]
    E --> F["Réponse de succès"]
    C -->|"Échec<br>(requête web)"| G["Redirection vers l'écran précédent<br>Erreurs stockées en session"]
    C -->|"Échec<br>(requête API)"| H["422 Unprocessable Entity<br>Réponse JSON d'erreur"]
```

## Validation dans le contrôleur

### `$request->validate()`

L'appel à `$request->validate()` dans une méthode de contrôleur est la méthode la plus simple.
En cas d'échec, Laravel redirige automatiquement vers l'écran précédent et stocke les erreurs en session.

Déclaration des routes :

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

Route::get('/post/create', [PostController::class, 'create']);
Route::post('/post', [PostController::class, 'store']);
```

Création du contrôleur :

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class PostController extends Controller
{
    public function create(): View
    {
        return view('post.create');
    }

    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'body'  => 'required|string',
            'email' => 'required|email',
        ]);

        // Enregistrement de la publication avec les données validées...

        return redirect('/posts');
    }
}
```

Passez à `validate` un tableau : nom du champ en clé, règles en valeur.
Séparez les règles avec `|` ou passez un tableau.

```php theme={null}
// Séparé par |
'title' => 'required|string|max:255',

// Tableau
'title' => ['required', 'string', 'max:255'],
```

### Règles principales

| Règle          | Description                                                |
| -------------- | ---------------------------------------------------------- |
| `required`     | La valeur doit être présente et non vide                   |
| `string`       | Doit être une chaîne                                       |
| `email`        | Doit être une adresse e-mail valide                        |
| `min:valeur`   | Longueur de chaîne ou valeur numérique supérieure ou égale |
| `max:valeur`   | Longueur de chaîne ou valeur numérique inférieure ou égale |
| `unique:table` | Valeur unique dans la table donnée                         |
| `nullable`     | Autorise `null`                                            |
| `integer`      | Doit être un entier                                        |
| `boolean`      | Doit être un booléen (`true`/`false`, `1`/`0`…)            |
| `date`         | Doit être une date valide                                  |
| `confirmed`    | Doit correspondre à un champ `nom_champ_confirmation`      |

<Info>
  Toutes les règles disponibles se trouvent dans la [documentation officielle](https://laravel.com/docs/validation#available-validation-rules).
</Info>

### Utiliser les données validées

`validate` retourne un tableau contenant uniquement les données validées. Vous pouvez les utiliser en toute confiance.

```php theme={null}
$validated = $request->validate([
    'title' => 'required|string|max:255',
    'body'  => 'required|string',
]);

// $validated a la forme ['title' => '...', 'body' => '...']
Post::create($validated);
```

## Affichage des erreurs dans Blade

En cas d'échec, Laravel rend la variable `$errors` disponible dans toutes les vues, grâce au middleware `ShareErrorsFromSession` inclus dans le groupe `web`.

### Afficher toutes les erreurs

```blade theme={null}
@if ($errors->any())
    <ul>
        @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>
@endif
```

### Afficher les erreurs par champ

`@error` affiche l'erreur d'un champ précis en inline.

```blade theme={null}
<label for="title">Titre</label>

<input
    id="title"
    type="text"
    name="title"
    value="{{ old('title') }}"
    class="@error('title') is-invalid @enderror"
/>

@error('title')
    <div class="error-message">{{ $message }}</div>
@enderror
```

<Tip>
  `old('nom_champ')` réaffiche la valeur saisie par l'utilisateur même après un échec de validation.
</Tip>

## Form requests

### Qu'est-ce qu'une form request

Quand la logique de validation devient complexe, il est efficace de l'externaliser dans une classe « form request ».
Elle regroupe la validation et l'autorisation dans une classe de requête personnalisée.

```mermaid theme={null}
flowchart TD
    A["Appel de la méthode de contrôleur"] --> B["Instanciation du FormRequest"]
    B --> C["Exécution de authorize()"]
    C --> D{{"Autorisation OK ?"}}
    D -->|"false"| E["Réponse 403 Forbidden"]
    D -->|"true"| F["Exécution de rules()"]
    F --> G["Validation"]
    G --> H{{"Validation<br>réussie ?"}}
    H -->|"Échec"| I["Réponse<br>d'erreur de validation"]
    H -->|"Succès"| J["Exécution de la méthode du contrôleur"]
```

### Créer une form request

Utilisez `make:request` pour générer la classe.

```shell theme={null}
php artisan make:request StorePostRequest
```

`app/Http/Requests/StorePostRequest.php` est généré.

```php theme={null}
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    /**
     * Détermine si l'utilisateur est autorisé à effectuer cette requête.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Règles de validation appliquées.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'title' => 'required|string|max:255',
            'body'  => 'required|string',
            'email' => 'required|email|unique:posts',
        ];
    }
}
```

### Méthode `rules()`

Retourne les règles de validation sous forme de tableau, comme celui passé à `validate`.

### Méthode `authorize()`

Détermine si l'utilisateur peut effectuer cette requête.
`true` autorise, `false` retourne automatiquement une réponse 403.

Pour n'autoriser que les utilisateurs authentifiés, vérifiez avec `auth()->check()`.
Dans un tutoriel, il est acceptable de retourner `true`.

<Warning>
  Si `authorize` retourne `false`, la méthode du contrôleur n'est pas exécutée : une réponse 403 est renvoyée.
</Warning>

### Injection dans le contrôleur

Il suffit de type-hinter la form request dans la méthode.
La validation s'exécute avant la méthode : vous n'écrivez plus de code de validation dans le contrôleur.

```php theme={null}
use App\Http\Requests\StorePostRequest;

class PostController extends Controller
{
    public function store(StorePostRequest $request): RedirectResponse
    {
        // À ce stade, la requête est validée

        $validated = $request->validated();

        Post::create($validated);

        return redirect('/posts');
    }
}
```

`$request->validated()` retourne uniquement les données validées.

## Exemple : formulaire de création et enregistrement

Enchaînement complet de l'affichage du formulaire à l'enregistrement.

<Steps>
  <Step title="Déclaration des routes">
    ```php theme={null}
    use App\Http\Controllers\PostController;

    Route::get('/posts/create', [PostController::class, 'create']);
    Route::post('/posts', [PostController::class, 'store']);
    ```
  </Step>

  <Step title="Création de la form request">
    ```shell theme={null}
    php artisan make:request StorePostRequest
    ```

    ```php theme={null}
    public function rules(): array
    {
        return [
            'title' => 'required|string|max:255',
            'body'  => 'required|string',
        ];
    }

    public function authorize(): bool
    {
        return true;
    }
    ```
  </Step>

  <Step title="Implémentation du contrôleur">
    ```php theme={null}
    use App\Http\Requests\StorePostRequest;
    use App\Models\Post;

    class PostController extends Controller
    {
        public function create(): View
        {
            return view('posts.create');
        }

        public function store(StorePostRequest $request): RedirectResponse
        {
            Post::create($request->validated());

            return redirect('/posts');
        }
    }
    ```
  </Step>

  <Step title="Création du template Blade">
    ```blade theme={null}
    {{-- resources/views/posts/create.blade.php --}}

    <h1>Nouvelle publication</h1>

    @if ($errors->any())
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    @endif

    <form method="POST" action="/posts">
        @csrf

        <div>
            <label for="title">Titre</label>
            <input
                id="title"
                type="text"
                name="title"
                value="{{ old('title') }}"
            />
            @error('title')
                <span>{{ $message }}</span>
            @enderror
        </div>

        <div>
            <label for="body">Contenu</label>
            <textarea id="body" name="body">{{ old('body') }}</textarea>
            @error('body')
                <span>{{ $message }}</span>
            @enderror
        </div>

        <button type="submit">Publier</button>
    </form>
    ```
  </Step>
</Steps>

<Info>
  Incluez toujours la directive `@csrf` dans les formulaires Blade. Sans le token CSRF, Laravel renvoie une erreur 419.
</Info>

## Prochaines étapes

<Card title="Requêtes HTTP" icon="arrow-up-from-bracket" href="/fr/requests">
  Revenez sur les moyens de récupérer les données via l'objet Request.
</Card>


## Related topics

- [Laravel Prompts](/fr/prompts.md)
- [Laravel MCP](/fr/mcp.md)
- [Règles de validation personnalisées](/fr/advanced/custom-validation-rules.md)
- [⚡Introduction à Livewire 4 — créer des UI réactives sans JavaScript](/fr/blog/livewire-introduction.md)
- [Mise à niveau de Laravel 9 vers 10](/fr/blog/upgrade-9-to-10.md)
