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

# Validierung

> Erfahren Sie, wie Sie mit den Validierungsfunktionen von Laravel Formulareingaben prüfen.

## Was ist Validierung

Validierung bedeutet, zu prüfen, ob vom Nutzer übermittelte Daten das erwartete Format und die Bedingungen erfüllen.
Laravel bietet dafür die einfache, aber leistungsfähige `validate`-Methode am Request-Objekt sowie eigene Form-Request-Klassen.

```mermaid theme={null}
flowchart TD
    A["HTTP-Request empfangen"] --> B["Validierungsregeln anwenden"]
    B --> C{{"Validierung<br>bestanden?"}}
    C -->|"Erfolg"| D["Validierte Daten abrufen"]
    D --> E["Controller-Logik ausführen"]
    E --> F["Erfolgs-Response"]
    C -->|"Fehler<br>(Web-Request)"| G["Redirect zur Vorseite<br>Fehler in Session"]
    C -->|"Fehler<br>(API-Request)"| H["422 Unprocessable Entity<br>JSON-Fehlerantwort"]
```

## Validierung im Controller

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

Der einfachste Weg ist der Aufruf von `$request->validate()` im Controller.
Schlägt die Validierung fehl, leitet Laravel automatisch zurück und speichert die Fehler in der Session.

Routen:

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

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

Controller:

```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',
        ]);

        // Mit den validierten Daten speichern...

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

`validate` erwartet ein Array aus Feldname → Regel.
Regeln trennen Sie per Pipe `|` oder in einem Array.

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

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

### Wichtige Validierungsregeln

| Regel            | Bedeutung                                       |
| ---------------- | ----------------------------------------------- |
| `required`       | Wert existiert und ist nicht leer               |
| `string`         | String                                          |
| `email`          | Gültige E-Mail                                  |
| `min:Wert`       | Länge oder Zahl mindestens angegebener Wert     |
| `max:Wert`       | Länge oder Zahl höchstens angegebener Wert      |
| `unique:tabelle` | Wert in der Tabelle einzigartig                 |
| `nullable`       | `null` ist erlaubt                              |
| `integer`        | Ganzzahl                                        |
| `boolean`        | Boolean (`true`/`false`, `1`/`0` etc.)          |
| `date`           | Gültiges Datumsformat                           |
| `confirmed`      | Muss mit `feldname_confirmation` übereinstimmen |

<Info>
  Alle Regeln finden Sie in der [offiziellen Dokumentation](https://laravel.com/docs/validation#available-validation-rules).
</Info>

### Nutzung der validierten Daten

Der Rückgabewert von `validate` enthält ausschließlich die validierten Werte – vertrauenswürdig zur Weiterverarbeitung.

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

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

## Fehleranzeige in Blade

Nach einer fehlgeschlagenen Validierung stellt Laravel automatisch die Variable `$errors` in allen Views zur Verfügung.
Dafür sorgt die Middleware `ShareErrorsFromSession` aus der `web`-Gruppe.

### Alle Fehler auflisten

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

### Fehler pro Feld

Mit `@error` zeigen Sie inline Fehler eines bestimmten Feldes.

```blade theme={null}
<label for="title">Titel</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>
  Mit `old('feldname')` behalten Sie den zuvor eingegebenen Wert im Formular auch nach einem Fehler.
</Tip>

## Form Requests

### Was sind Form Requests

Wenn die Validierungslogik komplexer wird, verlagern Sie sie in eine „Form-Request"-Klasse.
Ein Form Request bündelt Validierungs- und Autorisierungslogik in einer eigenen Request-Klasse.

```mermaid theme={null}
flowchart TD
    A["Controller-Methode aufrufen"] --> B["FormRequest-Instanz erzeugen"]
    B --> C["authorize() ausführen"]
    C --> D{{"Autorisierung OK?"}}
    D -->|"false"| E["403 Forbidden"]
    D -->|"true"| F["rules() ausführen"]
    F --> G["Validierung ausführen"]
    G --> H{{"Validierung<br>OK?"}}
    H -->|"Fehler"| I["Validierungs-<br>Fehlerantwort"]
    H -->|"OK"| J["Controller-Methode ausführen"]
```

### Form Request erzeugen

Mit `make:request`:

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

Erzeugt `app/Http/Requests/StorePostRequest.php`:

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

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    /**
     * Prüft, ob der Nutzer diese Aktion ausführen darf
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Regeln für diesen Request
     *
     * @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',
        ];
    }
}
```

### `rules()`

Gibt die Regeln als Array zurück – gleiches Format wie beim `validate`-Aufruf.

### `authorize()`

Prüft, ob der Nutzer diese Aktion ausführen darf.
`true` = erlaubt, `false` = automatisches 403 Forbidden.

Wollen Sie nur angemeldete Nutzer zulassen, prüfen Sie mit `auth()->check()`. Für Tutorials reicht `true`.

<Warning>
  Gibt `authorize()` `false` zurück, wird die Controller-Methode nicht ausgeführt und ein 403 zurückgegeben.
</Warning>

### Injection im Controller

Deklarieren Sie den Form Request einfach als Parameter. Die Validierung läuft vor der Methodenausführung.

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

class PostController extends Controller
{
    public function store(StorePostRequest $request): RedirectResponse
    {
        // Kommt der Code hier an, ist alles validiert

        $validated = $request->validated();

        Post::create($validated);

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

`$request->validated()` liefert nur die validierten Daten.

## Praxisbeispiel: Post-Formular anlegen und speichern

Kompletter Ablauf: Formular anzeigen, absenden, validieren, speichern.

<Steps>
  <Step title="Routen definieren">
    ```php theme={null}
    use App\Http\Controllers\PostController;

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

  <Step title="Form Request erzeugen">
    ```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="Controller implementieren">
    ```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="Blade-Template anlegen">
    ```blade theme={null}
    {{-- resources/views/posts/create.blade.php --}}

    <h1>Neuer Beitrag</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">Titel</label>
            <input
                id="title"
                type="text"
                name="title"
                value="{{ old('title') }}"
            />
            @error('title')
                <span>{{ $message }}</span>
            @enderror
        </div>

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

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

<Info>
  Vergessen Sie in Blade-Formularen nicht das `@csrf`-Directive – ohne CSRF-Token liefert Laravel Status 419.
</Info>

## Nächste Schritte

<Card title="HTTP-Requests" icon="arrow-up-from-bracket" href="/de/requests">
  Frischen Sie das Abrufen von Daten aus dem Request-Objekt auf.
</Card>


## Related topics

- [Laravel Prompts](/de/prompts.md)
- [Laravel MCP](/de/mcp.md)
- [HTTP-Tests](/de/http-tests.md)
- [Eigene Validierungsregeln](/de/advanced/custom-validation-rules.md)
- [⚡ Einführung in Livewire 4 – Reaktive UIs ohne JavaScript](/de/blog/livewire-introduction.md)
