Mastering Custom Validation Rules in Laravel
Beyond Built-In Constraints
required, string, and url. These work for 90% of use cases. However, real-world applications often demand more surgical precision. When you need to verify specific domain logic—like ensuring a
Prerequisites & Tools
To follow this guide, you should be comfortable with
- Artisan CLI: For generating rule boilerplate.
- Illuminate\Contracts\Validation\ValidationRule: The interface every custom rule must implement.
- PHPStorm / Laravel Idea: Recommended for autocompletion and rule discovery.
The Anatomy of a Custom Rule
Generate a new rule using the terminal command: php artisan make:rule YouTubeURLRule. This creates a class in the app/Rules directory. The heart of this class is the validate method.
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (!preg_match('/^https?:\/\/(?:www\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)([\w-]{11})/', $value, $matches)) {
$fail('The :attribute is not a valid YouTube URL.');
}
}
The $attribute is the field name (e.g., youtube_url), $value is the user input, and $fail is the callback you trigger if the validation doesn't pass.
External API Integration
Custom rules aren't limited to string manipulation. You can perform network requests to verify data existence. For instance, to check if a video actually exists, you can call the validate method. If the API returns a 404, simply call the $fail closure. This transforms a simple syntax check into a powerful data integrity tool.
Implementation in Controllers
To use your new rule, instantiate it within your controller's validation array:
$request->validate([
'video_url' => ['required', new YouTubeURLRule],
]);
Syntax & Best Practices
- Type Hinting: Always type hint the
$valueto ensure your logic handles the data correctly. - Reusability: Keep rules generic. Instead of hardcoding error messages, use Laravel's translation strings to keep your code clean and localizable.
- Performance: Be cautious with API calls inside validation rules; consider caching results if the same value is validated frequently.
