Leverage Turing Intelligence capabilities to integrate AI into your operations, enhance automation, and optimize cloud migration for scalable impact.
Advance foundation model research and improve LLM reasoning, coding, and multimodal capabilities with Turing AGI Advancement.
Access a global network of elite AI professionals through Turing Jobs—vetted experts ready to accelerate your AI initiatives.
While you are working with user input and forms, validating the common fields and extracting the exact validation rules makes the code easier to maintain and read. You can make the code powerful by using the Laravel custom validation rule with parameters. This streamlines the flow between the logic and code wherever required.
Laravel offers various convenient validation rules that can be applied to the data if values are specific to a database table. In this insightful article, we will cover all the validation rules in detail to make you familiar with the features of these validation rules.
To brush up on your knowledge, let’s consider an example of form validation and portray the error message to the user. We will walk you through this overview so you can have a complete understanding of how to validate an incoming data request in Laravel.
Let’s take an example where we define the following routes in our ‘routes/web.php’ file.
use App\Http\Controllers\PostController;Route::get('/post/create', [PostController::class, 'create']); Route::post('/post', [PostController::class, 'store']);
In the above code, the ‘GET’ route will depict a form to create a new post. The ‘POST’ route shares the new post in the database.
Now let’s understand how an easy controller handles the incoming data requests regarding these routes.
<?phpnamespace App\Http\Controllers;
use App\Http\Controllers\Controller; use Illuminate\Http\Request;
class PostController extends Controller { /** * Show the form to create a new blog post. * * @return \Illuminate\View\View */ public function create() { return view('post.create'); }
/** * Store a new blog post. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { // Validate and store the blog post... } }
After creating a new controller, we are ready to prepare and implement the store method with the logic to validate the new post. To do this, we need to validate the methods provided by the ‘Illuminate\Http\Request’ object. If the validation rules pass, the code that has been prepared will execute normally. Apart from a successful run, if the validation fails, the ‘Illuminate\Validation\ValidationException’ is disowned and the error message is displayed.
If the validation fails during a traditional HTTP request, a direct response is sent to the previous URL. In the case of an XHR request, a JSON response that contains the error message is displayed.
Let’s go back to the store method and dive deeper into the validation approach.
/** * Store a new blog post. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $validated = $request->validate([ 'title' => 'required|unique:posts|max:255', 'body' => 'required', ]);// The blog post is valid... }
All the general validation rules are recorded properly. In case, the validation can’t perform, a proper response is automatically generated.
$validatedData = $request->validate([ 'title' => ['required', 'unique:posts', 'max:255'], 'body' => ['required'], ]);
You can specify the nested fields in your validation rules using the ‘dot’ syntax in case the incoming HTTP request includes the nested field data.
$request->validate([ 'title' => 'required|unique:posts|max:255', 'author.name' => 'required', 'author.description' => 'required', ]);
Alternatively, if the field holds a literal period, you can stop this from being analyzed as the ‘dot’ syntax by exiting the period using a backslash.
$request->validate([ 'title' => 'required|unique:posts|max:255', 'v1\.0' => 'required', ]);
This is the second phase of the entire process. Let us check out the different sub-processes.
You may implement a ‘form request’ for a more complicated Laravel custom validation rule. To build a form request class, it is necessary to use the Artisan CLI command:
php artisan make:request StorePostRequest
The form request class you prepared is placed in the ‘app/Http/Requests’ directory. Every form request comprises two methods:
/** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'title' => 'required|unique:posts|max:255', 'body' => 'required', ]; }
So how do you validate the rules? You have to type-hint the request on the controller method. The incoming form request will be validated prior to the controller method being implemented and it allows you to declutter your controller with the validation logic.
Let us understand this process with the code below.
/** * Store a new blog post. * * @param \App\Http\Requests\StorePostRequest $request * @return Illuminate\Http\Response */ public function store(StorePostRequest $request) { // The incoming request is valid...// Retrieve the validated input data... $validated = $request->validated();
// Retrieve a portion of the validated input data... $validated = $request->safe()->only(['name', 'email']); $validated = $request->safe()->except(['name', 'email']);
When you want to add an ‘after’ validation hook to a form request, you can do that by using the ‘withValidator’ approach. This approach receives a completely constructed validator and allows you to call the sub-methods before the validation rules are analyzed.
/** * Configure the validator instance. * * @param \Illuminate\Validation\Validator $validator * @return void */ public function withValidator($validator) { $validator->after(function ($validator) { if ($this->somethingElseIsInvalid()) { $validator->errors()->add('field', 'Something is wrong with this field!'); } }); }
You can notify the validator to stop validating the attributes if there is a failure. You can do this by adding a ‘stopOnFirstFailure’ function to your request class.
/** * Indicates if the validator should stop on the first rule failure. * * @var bool */ protected $stopOnFirstFailure = true;
As we discussed previously, a direct response is generated and sent back to the user to the previous location in case of a validation failure. Nonetheless, you can customize a redirect route by defining a ‘$redirect’ property.
/** * The URI that users should be redirected to if validation fails. * * @var string */ protected $redirect = '/dashboard';
The form request class has an Authorize method using which you can evaluate when the authenticated user has permission to update a resource. For example, you can evaluate if the user has the authority to update a blog post or a comment. Here is the code fragment to better understand how to authorize the form request.
use App\Models\Comment;/**
Determine if the user is authorized to make this request.
@return bool */ public function authorize() { $comment = Comment::find($this->route('comment'));
return $comment && $this->user()->can('update', $comment); }
If this method returns False, then an HTTP response with a 403 status code is generated and your methods will not be executed. You can simply return the ‘true’ from the authorized method if you want to handle the authorization logic for requests in any other part of your application.
/**
Determine if the user is authorized to make this request.
@return bool */ public function authorize() { return true; }
You can prepare any data from the request before you implement your validation rules. To do that, you have to implement the ‘prepareForValidation’ approach. The code fragment below shows how to do that.
use Illuminate\Support\Str;/**
Here is how you can create your Laravel validation custom rules and implement them. This step is fragmented into multiple small steps.
You can choose not to validate a field if it contains a value. To do so, you can use the ‘exclude_if’ rule.
In the example, there are two fields.
These two fields won’t be validated if the ‘has_appointment field’ has a false value.
use Illuminate\Support\Facades\Validator;$validator = Validator::make($data, [ 'has_appointment' => 'required|boolean', 'appointment_date' => 'exclude_if:has_appointment,false|required|date', 'doctor_name' => 'exclude_if:has_appointment,false|required|string', ]);
You can wish to add the validation rules based on complex logic according to a few conditions. To do this, you have to have two fields with values only when a different field is present. In the code below, we have created a validator with the static rules.
use Illuminate\Support\Facades\Validator;$validator = Validator::make($request->all(), [ 'email' => 'required|email', 'games' => 'required|numeric', ]);
If you do not know the index, you can validate a field based on another field in the same nested array. In such a scenario, you can have a second argument that becomes the current item in the array you want to validate.
$input = [ 'channels' => [ [ 'type' => 'email', 'address' => 'abigail@example.com', ], [ 'type' => 'url', 'address' => 'https://example.com', ], ], ];$validator->sometimes('channels.*.address', 'email', function ($input, $item) { return $item->type === 'email'; });
$validator->sometimes('channels.*.address', 'url', function ($input, $item) { return $item->type !== 'email'; });
You can use Laravel’s password rule object to ensure that the passwords have a decent level of complexity.
use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rules\Password;$validator = Validator::make($request->all(), [ 'password' => ['required', 'confirmed', Password::min(8)], ]);
The password rule object enables you to customize the complexity needed for your application. You can have complex passwords that have these compulsory requirements:
// Require at least 8 characters... Password::min(8)// Require at least one letter... Password::min(8)->letters()
// Require at least one uppercase and one lowercase letter... Password::min(8)->mixedCase()
// Require at least one number... Password::min(8)->numbers()
// Require at least one symbol... Password::min(8)->symbols()
Apart from the above method, you can have more security and complexity to your passwords using the ‘uncompromised’ method.
Password::min(8)->uncompromised()
If a password appears at least once in a data leak, it is treated as ‘compromised’. You can customize this constraint using the first argument of the ‘uncompromised method. Here is the code fragment to do so.
// Ensure the password appears less than 3 times in the same data leak... Password::min(8)->uncompromised(3);
After these steps, you are ready to create customized validation rules. There are three broad categories under which you can customize them.
Let’s have a quick walkthrough.
Laravel offers a wide variety of useful validation rules and you can also customize some of your own if you wish to. One popular method of registering the custom validation rules is by using the rule objects.
If you wish to customize a new rule object, you can use the Artisan command. Let’s understand this approach by customizing a rule that determines if a string is uppercase. Laravel enables you to place the new rule in the ‘app/Rules’ directory.
php artisan make:rule Uppercase --invokable
Once you have created a new rule, you can define its behavior. A new rule object contains ‘__invoke’. This method receives the following:
The callback is invoked upon failure with an error message.
<?phpnamespace App\Rules;
use Illuminate\Contracts\Validation\InvokableRule;
class Uppercase implements InvokableRule { /** * Run the validation rule. * * @param string $attribute * @param mixed $value * @param \Closure $fail * @return void */ public function __invoke($attribute, $value, $fail) { if (strtoupper($value) !== $value) { $fail('The :attribute must be uppercase.'); } } }
In the case you only need the functionality of a custom rule only once throughout your application, you can use a closure. The closure receives the following:
The $fail callback is called upon validation failure.
use Illuminate\Support\Facades\Validator;$validator = Validator::make($request->all(), [ 'title' => [ 'required', 'max:255', function ($attribute, $value, $fail) { if ($value === 'foo') { $fail('The '.$attribute.' is invalid.'); } }, ], ]);
When an attribute, being validated, is absent then the Laravel custom validation rule cannot be implemented. Below is an example where the unique custom cannot run in the case of an empty string.
use Illuminate\Support\Facades\Validator;$rules = ['name' => 'unique:users,name'];
$input = ['name' => ''];
Validator::make($input, $rules)->passes(); // true
To run a rule when an attribute is empty, ensure that the attribute under consideration is required. To customize an implicit rule, you can implement the ‘Illuminate\Contracts\Validation\ImplicitRule’.
The above is implemented on an interface that serves as a ‘marker interface’ for the validator. This interface does not contain any methods to implement the typical rule interface.
Laravel is widely popular in web development, but its packages can be used to customize the validation rules. This powerful framework also offers tons of built-in functionalities with a set of validators that can be used to validate the request forms.
In some tricky situations, we need a customized validator that can address specific purposes. Laravel enables you to create these custom validators. For better efficiency, remember this:
Implement the Closure and Extend approach present in the validator and use the Rule command to create a ruling class.
Jay is a seasoned writer with 7+ years of experience in content marketing. Long-form content, copywriting, and UX writing are his strengths. He also enjoys singing, cooking, and composing poetry.