Laravel Validation ist der sauberste Weg, eingehende Request-Daten sicher und konsistent zu prüfen, bevor sie überhaupt in die Nähe deiner Controller-Logik gelangen. Eine gut strukturierte Validierung gibt Nutzern klares Feedback und verhindert, dass fehlerhafte Daten jemals deine Datenbank erreichen. In diesem Artikel zeige ich den Ansatz, den ich in der Praxis tatsächlich verwende: von der Regelsyntax über Form-Request-Klassen bis zu eigenen Regeln und der Verwaltung von Fehlermeldungen.
Der schnellste Weg: validate() im Controller
Für kleine Formulare ist es am praktischsten, $request->validate() direkt in der Controller-Methode aufzurufen. Bestehen die Regeln, läuft die Ausführung weiter; schlagen sie fehl, leitet Laravel automatisch zurück und legt die Fehler in der Session ab (oder gibt bei JSON-Requests einen 422 zurück).
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'email' => 'required|email',
'age' => 'nullable|integer|min:18',
'tags' => 'array',
'tags.*' => 'string|max:30',
]);
Post::create($validated);
return redirect()->route('posts.index');
}
Ein wichtiges Detail: validate() gibt nur die Felder zurück, die du tatsächlich validiert hast. Das ist auch ein Sicherheitsgewinn, weil es verhindert, dass zusätzliche, unerwünschte Felder ins Modell durchsickern (Mass Assignment). Statt Regeln mit Pipes zu verketten, kannst du auch die Array-Form nutzen; bei komplexen Regeln mit Rule-Objekten ist die Array-Form deutlich lesbarer.
Häufige Regeln und ihre Logik
Laravel bringt Hunderte eingebauter Regeln mit. Im Alltag greifst du am häufigsten zu diesen:
required/nullable— ob ein Feld Pflicht ist oder leer bleiben darf.string,integer,boolean,array,date— Typprüfungen.min/max/between— Wert bei Zahlen, Zeichen bei Strings, Anzahl der Elemente bei Arrays.email,url,uuid— Formatvalidierung.unique:table,columnundexists:table,column— datenbankgestützte Prüfungen.confirmed— verlangt, dasspasswordmit einem Feldpassword_confirmationübereinstimmt.
Für bedingte Logik sind Varianten wie required_if, required_with und required_without wahre Lebensretter. Zum Beispiel wird „Kartennummer ist erforderlich, wenn der Zahlungstyp Karte ist" zu einer einzigen Zeile: 'card_number' => 'required_if:payment,card'.
Form Request: Validierung aus dem Controller auslagern
Wenn die Regeln wachsen, bläht sich der Controller auf. Die richtige Lösung ist eine Form-Request-Klasse. Sie bündelt Autorisierung, Regeln und Meldungen an einer Stelle.
php artisan make:request StorePostRequest
class StorePostRequest extends FormRequest
{
public function authorize(): bool
{
return $this->user()->can('create', Post::class);
}
public function rules(): array
{
return [
'title' => ['required', 'string', 'max:255'],
'slug' => ['required', 'string', Rule::unique('posts')],
'body' => ['required', 'string'],
];
}
}
Anschließend gibst du diese Klasse einfach als Type-Hint in der Controller-Methode an. Laravel validiert den Request automatisch und betritt die Methode bei einem Fehler gar nicht erst:
public function store(StorePostRequest $request)
{
Post::create($request->validated());
}
Gibt authorize() false zurück, entsteht ein 403; erledigst du die Autorisierung in einer separaten Schicht, kannst du diese Methode einfach auf return true; lassen. Der Form-Request-Ansatz erleichtert auch das Testen, weil du die Regeln isoliert validieren kannst.
Eigene Regeln und Closure-Regeln
Wenn die eingebauten Regeln nicht ausreichen, hast du zwei Möglichkeiten. Für eine einmalige Prüfung ist eine Closure am schnellsten:
'slug' => [
'required',
function (string $attribute, mixed $value, Closure $fail) {
if (str_contains($value, ' ')) {
$fail("Das Feld $attribute darf keine Leerzeichen enthalten.");
}
},
],
Wenn du dieselbe Regel an mehreren Stellen wiederverwendest, ist eine wiederverwendbare Regelklasse sauberer:
php artisan make:rule Uppercase
class Uppercase implements ValidationRule
{
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (strtoupper($value) !== $value) {
$fail('The :attribute must be uppercase.');
}
}
}
Die Verwendung ist wie bei jeder anderen Regel: 'code' => ['required', new Uppercase]. Der Platzhalter :attribute in der Meldung wird automatisch durch den Feldnamen ersetzt.
Fehlermeldungen verwalten
Die Standardmeldungen sind auf Englisch und generisch. Für freundlichere, lokalisierte Meldungen überschreibst du die Methoden messages() und attributes() in der Form Request:
public function messages(): array
{
return [
'title.required' => 'Das Titelfeld ist erforderlich.',
'title.max' => 'Der Titel darf nicht mehr als :max Zeichen haben.',
];
}
public function attributes(): array
{
return ['title' => 'Titel'];
}
Auf der Blade-Seite reichen die Direktive @error und der Helfer old() völlig aus; old() sorgt dafür, dass die Eingabe des Nutzers nicht verschwindet, wenn das Formular neu gerendert wird:
<input name="title" value="{{ old('title') }}">
@error('title')
<span class="error">{{ $message }}</span>
@enderror
In mehrsprachigen Projekten ist es wartungsfreundlicher, Meldungen nicht hart in den Code zu schreiben, sondern die Übersetzungsdateien im Verzeichnis lang/ zu nutzen. So kannst du dasselbe Regelwerk konsistent in verschiedenen Sprachen ausliefern.
Häufige Fragen
Was ist der Unterschied zwischen validate() und einer Form Request?
Beide nutzen dieselbe Engine. validate() ist ideal für schnelle, kleine Formulare; eine Form Request bündelt Regeln, Autorisierung und Meldungen in einer eigenen Klasse, hält den Controller sauber und erleichtert die Wiederverwendung.
Wie werden Validierungsfehler bei API-Requests zurückgegeben?
Trägt der Request einen Accept: application/json-Header, leitet Laravel nicht um; es gibt eine JSON-Antwort mit dem Status 422 Unprocessable Entity und einem errors-Objekt zurück. Das Frontend kann diese Struktur direkt verarbeiten.
Kann ich ein Feld nur unter einer bestimmten Bedingung validieren?
Ja. Du kannst bedingte Regeln wie required_if verwenden oder zur Laufzeit dynamische Regeln mit der Methode sometimes() in einer Form Request hinzufügen.
Die Validierungsschicht ist das Sicherheitsfundament deines Projekts. Wenn du deine Laravel-Validation-Architektur sauber und testbar gestalten oder die komplexen Regeln in einem bestehenden Formular aufräumen möchtest, nimm Kontakt mit mir auf.