intermediate
Step 12 of 15
Validation and Form Requests
Laravel Framework
Validation and Form Requests
Input validation is one of the most important aspects of web application security and data integrity. Laravel provides an expressive, powerful validation system that handles everything from simple required fields to complex conditional rules, custom validation logic, and localized error messages. Form Request classes encapsulate validation logic into dedicated classes, keeping your controllers clean and your validation rules reusable. Laravel's validation integrates seamlessly with Blade templates to display error messages alongside form fields.
Validation Rules
<?php
// Inline validation in controller
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'age' => 'required|integer|between:18,120',
'website' => 'nullable|url',
'avatar' => 'nullable|image|max:2048|mimes:jpg,png,webp',
'tags' => 'required|array|min:1|max:5',
'tags.*' => 'string|max:50',
'password' => 'required|min:8|confirmed',
]);
// $validated contains only the validated fields
User::create($validated);
}
// Form Request class (recommended for complex validation)
// php artisan make:request StorePostRequest
class StorePostRequest extends FormRequest
{
public function authorize(): bool
{
return true; // or check permissions
}
public function rules(): array
{
return [
'title' => 'required|string|max:255|unique:posts',
'body' => 'required|string|min:100',
'category' => 'required|in:tech,news,tutorial,review',
'published_at' => 'nullable|date|after:today',
];
}
public function messages(): array
{
return [
'title.required' => 'Every post needs a title.',
'body.min' => 'Post content must be at least 100 characters.',
];
}
}
// Controller uses the Form Request for automatic validation
public function store(StorePostRequest $request)
{
// Validation already passed — $request->validated() has clean data
$post = Post::create($request->validated());
return redirect()->route('posts.show', $post);
}
Displaying Errors in Blade
<form method="POST" action="/posts">
@csrf
<div>
<label for="title">Title</label>
<input type="text" name="title" value="{{ old('title') }}"
class="@error('title') is-invalid @enderror">
@error('title')
<span class="error">{{ $message }}</span>
@enderror
</div>
<button type="submit">Create Post</button>
</form>
Pro tip: Use Form Request classes instead of inline validation for any form with more than 2-3 fields. They keep controllers thin, make validation rules reusable and testable, and provide a clear place for authorization checks. Use old('field') in Blade to repopulate form fields after validation failure.
Key Takeaways
- Laravel validation supports 90+ built-in rules including required, email, unique, between, and regex.
- Form Request classes encapsulate validation and authorization logic in dedicated, reusable classes.
- Use
old('field')to repopulate form fields and@errordirective to display messages. - Array validation uses dot notation:
'tags.*' => 'string'validates each array element. - Custom validation messages improve user experience with clear, domain-specific error text.