Generate custom, reusable validation rule objects using php artisan make:rule with the Illuminate\Contracts\Validation\ValidationRule interface.
When complex validation logic (such as validating tax IDs, verifying phone carrier formats, or checking credit card checksums) is needed across multiple Form Requests, writing custom closures or regexes leads to duplicate code.
Laravel provides the ValidationRule contract for custom rule classes.
Generating a Custom Rule
php artisan make:rule Uppercase
Implementing the Rule Class
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class Uppercase implements ValidationRule
{
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (strtoupper($value) !== $value) {
$fail("The :attribute must be completely uppercase.");
}
}
}
Using the Rule in Form Requests
use App\Rules\Uppercase;
public function rules(): array
{
return [
'promo_code' => ['required', 'string', new Uppercase()],
];
}
Summary
- Uses the modern single-method
validate($attribute, $value, $fail)interface. - Invoke
$fail('message')to record validation failures. - Highly testable and reusable across Form Requests and Validator instances.
Related Tips
View all tips →Reject Mutually Exclusive Inputs with Rule::prohibitedIf()
Use Rule::prohibitedIf() and Rule::prohibited() to ensure specific fields cannot be submitted based on other form selections.
Apply Conditional Validation with Validator::sometimes()
Use Validator::sometimes() to apply validation rules only when a specific input field is present or when a custom closure returns true.