How FormRequest validation works in Laravel(PHP)
Form Request validation is very simple and elegant way to validate input data coming from the client side. As you may already know how to use it, this tutorial is about internal working of FormRequst.
This toutorial assumes that you have some basic knowledge of Laravel's Service Providers and Container.
For FormRequest validation, Laravel use FoundationServiceProvider which is defined in confg/app.php.
This tutorial contains two parts.
- How Laravel handles the flow to FoundationServiceProvider.
- How FoundationServiceProvider make FormRequst to work.
Part 1
How Laravel call FoundationServiceProvider
During starup process of Laravel, it calls the boot method of every ServiceProvider and the boot method of Illuminate\Foundation\Application is responsible for this .
Here is the boot method of Application class…
public function boot()
?{
if ($this->booted)
{
return;
}
$this->fireAppCallbacks($this->bootingCallbacks);
array_walk($this->serviceProviders, function ($p) {
$this->bootProvider($p);
});
$this->booted = true;
$this->fireAppCallbacks($this->bootedCallbacks);
}
The code of our concern is
array_walk($this->serviceProviders, function ($p) {
$this->bootProvider($p);
});
protected function bootProvider(ServiceProvider $provider)
?{
if (method_exists($provider, 'boot')) {
return $this->call([$provider, 'boot']);
}
}
This piece of code calls boot method of each serviceProvider defined in config/app.php. In this process, the boot method of FoundationServiceProvider also gets called.
Now at this point we have completed our first part of tutorial successfully.
Part 2:
How FoundationServiceProvider make FormRequst to work
FoundationServiceProvider uses resolving and afterResolving events of service container. Container fires these events every time it resolves an object.
It is easy to learn code by looking at code. So here is the code of boot method of FoundationServiceProvider.
/**
? * Bootstrap the application services.
?*
?* @return void
*?
? */
?public function boot()
?{
$this->configureFormRequests();
}
/**
? * Configure the form request related services.
? *
? * @return void
? */
?protected function configureFormRequests()
?{
/**
? * register function as after resolving callbacks
? */
? $this->app->afterResolving(function (ValidatesWhenResolved $resolved) {
$resolved->validate();
});
$this->app->resolving(function (FormRequest $request, $app) {
$this->initializeRequest($request, $app['request']);
$request->setContainer($app)
->setRedirector($app
->make(Redirector::class));
});
}
In this function, FoundatonServiceProvider registers two callbacks to be fired whenever container resolves FormRequest type object.
First callback to be fired after Container has resolved the FormRequest Object and second one to be called before resolving this object.
Callback for resolving event
$this->app->resolving(function (FormRequest $request, $app) {
$this->initializeRequest($request, $app['request']);
$request->setContainer($app)
->setRedirector($app->make(Redirector::class));
});
This callback initializes FormRequest object from Illuminate\Http\Request object.
Callback for afterResolving event
$this->app->afterResolving(function (ValidatesWhenResolved $resolved) {
$resolved->validate();
});
Service container will fire this callback after resolution of ValidatesWhenResolved type object.
As ValidatesWhenResolved is an interface and FormRequest implements this interface, so eventually validate method of FormRequest is going to be called. It is defined in Illuminate\Validation\ValidatesWhenResolvedTrait trait, used by FormRequest.
Let give a look to validate method.
public function validate()
{
$instance = $this->getValidatorInstance();
if (! $this->passesAuthorization()) {
$this->failedAuthorization();
} elseif (! $instance->passes()) {
$this->failedValidation($instance);
}
}
This method performs three steps.
- makes ValidationFactory object ($this->getValidatorInstance())
- checks if user is authorize ($this->passesAuthorization())
- Validates rules ($instance->passes()). This is method of Illuminate\Validation\Validator class which spins through all rules and executes them.
That’s all. I hope you understood the process. It’s all there in the source code of Laravel. Enjoy
Junior Software Developer at Routeique - Cloud-based Logistics & Delivery Management
6 年good?
DevOps Engineer at Bazingo Inc.
7 年(Y)
Full Stack Developer || Laravel || Vuejs
7 年Saquib if you want to validate file type, you can use mimes or mimetypes rule.
Software Engineer at Contour Software
7 年Good article. Validations are important for every form. Have you written an article for validating a file uploading? I am in search for that.
PHP Developer(Laravel framework) and Frontend designer at Internetesolutions.com
7 年i want to work in laravel. I have experienced in laravel near about 8 month, many website convert in laravel and create new module in these sites www.globalitrack.com