- 1. Keep Your Controllers Clean: Form Requests
- 2. Make Your Own Rules: Custom Rule Objects
- 3. Smart Validation: Conditional Rules
- 4. Manipulating Data: Preparing Input For Validation
- 5. The Modern Way to Validate Passwords: The Password Rule
- Conclusion
Advanced Laravel Validation Techniques and Tips
Hey there, fellow developers! When we’re building applications with Laravel, one of the features we all use constantly is validation. We all know and love the basic rules like required
, email
, min
, and max
. But what happens when things get a bit more complex?
Are you tired of validation logic bloating your controllers? Have you ever found yourself thinking, “I wish this field was only required under a specific condition”?
If these questions sound familiar, you’re in the right place. In this post, we’ll go beyond the basics and dive into advanced techniques and lesser-known tips that will make your Laravel validation code cleaner, more readable, and more powerful. Buckle up, because you’re about to level up your validation game!
1. Keep Your Controllers Clean: Form Requests
Let’s kick things off with one of my absolute favorite techniques: Form Requests. Instead of calling the validate()
method inside your controller, you can consolidate all of your validation and authorization logic into dedicated request classes. This cleans up your controllers immensely, especially when you’re dealing with complex forms.
To create a Form Request, all you need to do is run a simple Artisan command:
php artisan make:request StoreBlogPostRequest
This command will create a new StoreBlogPostRequest
class in your app/Http/Requests
directory. Inside this class, you’ll find two main methods: authorize
and rules
.
authorize()
: This method is where you can determine if the authenticated user has the permission to make this request. For example, only the author of a blog post should be able to update it. For now, we can just leave this astrue
.rules()
: This is where the magic happens! You return an array of all your validation rules from this method.
Here’s a simple example:
// app/Http/Requests/StoreBlogPostRequest.php
public function rules(): array
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
So how do you use this in your controller? You simply type-hint the class in your controller method’s signature:
// app/Http/Controllers/PostController.php
use App\Http\Requests\StoreBlogPostRequest;
public function store(StoreBlogPostRequest $request)
{
// If we reach this point, the validation was successful.
// You can get the validated data:
$validated = $request->validated();
// ... Your remaining logic ...
}
Look at that—our controller method is squeaky clean! The validation logic has been completely offloaded to the StoreBlogPostRequest
class. If validation fails, Laravel automatically redirects the user back to the previous page with all the error messages flashed to the session.
2. Make Your Own Rules: Custom Rule Objects
Sometimes, Laravel’s built-in rules just don’t cut it. Maybe you need to ensure a username follows a specific internal format, or you want to check if an ISBN number is valid. This is where creating our own custom rule objects comes in.
Once again, Artisan comes to our rescue:
php artisan make:rule MustBeUppercase
This command creates a new rule class in app/Rules
. The validate
method within this class houses all the logic:
// app/Rules/MustBeUppercase.php
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class MustBeUppercase implements ValidationRule
{
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (strtoupper($value) !== $value) {
// Call the $fail callback on failure.
$fail('The :attribute field must be entirely uppercase.');
}
}
}
Using this rule is a breeze. Just instantiate it directly in your rules array:
use App\Rules\MustBeUppercase;
$request->validate([
'name' => ['required', 'string', new MustBeUppercase],
]);
This allows you to create reusable, testable, single-responsibility rule classes that you can use throughout your application.
3. Smart Validation: Conditional Rules
Does this scenario sound familiar? “This field should only be required if that checkbox is ticked.” Laravel’s conditional validation features are built for exactly this.
sometimes
Rule
The The sometimes
rule specifies that a field should only be validated if it’s actually present in the request data. This means if the field isn’t sent at all, other rules like required
or email
won’t be triggered.
$validator = Validator::make($data, [
'email' => 'sometimes|required|email',
]);
In the example above, if the email
field isn’t included in the form submission, no validation runs. But if it is present, it must not be empty and must be a valid email address.
exclude_if
and required_if
For more complex scenarios, rules like exclude_if
and required_if
are fantastic. For example, you might require a delivery address only if the user has selected a “ship to home” option.
$request->validate([
'wants_delivery' => 'required|boolean',
'delivery_address' => 'required_if:wants_delivery,true|string|max:255',
]);
This rule ensures that delivery_address
is only required when the wants_delivery
field is true
.
4. Manipulating Data: Preparing Input For Validation
Sometimes, you need to “clean up” or modify the incoming data before your validation rules run. For example, you might want to automatically generate a slug
from the title
field the user submitted. The prepareForValidation
method in a Form Request is the perfect place for this.
// app/Http/Requests/StoreBlogPostRequest.php
use Illuminate\Support\Str;
protected function prepareForValidation(): void
{
$this->merge([
'slug' => Str::slug($this->title),
]);
}
This method is called right before the validation rules are executed. We’re merging a new slug
field into the request, which we can now also validate in our rules
method.
Password
Rule
5. The Modern Way to Validate Passwords: The Enforcing strong password policies is crucial for security. Laravel provides an elegant Password
rule object that makes this easy.
Using a fluent interface, you can chain methods to specify exactly how complex a password needs to be:
use Illuminate\Validation\Rules\Password;
$request->validate([
'password' => [
'required',
'confirmed',
Password::min(8) // Must be at least 8 characters. [1]
->letters() // Must contain at least one letter. [1]
->mixedCase() // Must contain both uppercase and lowercase letters. [1]
->numbers() // Must contain at least one number. [1]
->symbols() // Must contain at least one symbol. [1]
->uncompromised(), // Must not have appeared in a data leak. [1]
],
]);
That uncompromised()
method is especially brilliant. It checks if the password has appeared in known data breaches using the “Have I Been Pwned” service, without ever compromising the user’s privacy or the password itself.
Conclusion
Laravel’s validation engine is far more powerful and flexible than it might seem at first glance. From keeping controllers clean with Form Requests to writing your own custom rules, and from conditional logic to modern tools like the Password
object, you can make your applications more robust and easier to maintain.
Don’t hesitate to experiment with these techniques in your projects. While it might feel like a bit more code upfront, the time and maintainability you’ll gain in the long run are priceless.
Happy coding
Add Comment
No comments yet. Be the first to comment!