I need to deeply understand laravel. I have to explain everything to my dev team since we are starting to use laravel.
Please correct this if it is wrong: When laravel s
I wanted to know the answer to this as well, but I decided to look for myself instead.
If you go to app/storage/meta
there is a services.json
that lists the eager
and deferred
classes. This is so we don't load all classes for every request as we may never need the Form
class if we are building an API.
The ProviderRepository
class scans all the providers listed in app/config/app.php
and instantiates the providers for each of them (These are not the actual libraries).
These providers eg CacheServiceProvider
in Illuminate/Cache
have a variable called defer
that determines whether the library will be eagerly loaded of deferred until needed.
Here is a quote from ProviderRepository
When recompiling the service manifest, we will spin through each of the providers and check if it's a deferred provider or not. If so we'll add it's provided services to the manifest and note the provider.
For the CacheServiceProvider
this is set to true
.
So lets say Validator::make()
is called here is what I have gathered; Each Facade
such as the Validator
facade extends the base Facade
class in Illuminate\Support\Facades\Facade
.
This has a magic method __callStatic($method, $args)
which is quite self explanatory, the main point of this method is
$instance = static::resolveFacadeInstance(static::getFacadeAccessor());
The facade accessor in this case returns a string of the actual class that performs the validation (Illuminate\Validation\Validator
):
protected static function getFacadeAccessor() { return 'validator'; }
The main method resolveFacadeInstance
checks if the returned accessor is an object. If it is it simply returns that back as it is probably a custom Laravel package.
The second part of this method checks if it has already been resolved, if it has then return that. The final part:
return static::$resolvedInstance[$name] = static::$app[$name];
Calls the Illuminate\Foundation\Application
(which extends the Illuminate\Container\Container
class) via the array access interface located in the previously mentioned parent class.
So static::$app[$name]
calls:
public function offsetGet($key)
{
return $this->make($key);
}
This is located in the Container
class
Which leads us to the make()
method in the Application
class:
public function make($abstract, $parameters = array())
{
if (isset($this->deferredServices[$abstract]))
{
$this->loadDeferredProvider($abstract);
}
return parent::make($abstract, $parameters);
}
I'll let you delve into the parent::make()
method as this would start getting very lengthy, but as it stands this is where it loads the deferred provider and instantiates it via the loadDeferredProvider()
public function loadDeferredProviders()
{
// We will simply spin through each of the deferred providers and register each
// one and boot them if the application has booted. This should make each of
// the remaining services available to this application for immediate use.
foreach (array_unique($this->deferredServices) as $provider)
{
$this->register($instance = new $provider($this));
if ($this->booted) $instance->boot();
}
$this->deferredServices = array();
}
The comments in the code block should explain the rest of what is happening.
From here, the last part of __callStatic($method, $args)
fires the actual method called Validator::make()
.
public static function __callStatic($method, $args)
{
$instance = static::resolveFacadeInstance(static::getFacadeAccessor());
switch (count($args))
{
case 0:
return $instance->$method();
case 1:
return $instance->$method($args[0]);
case 2:
return $instance->$method($args[0], $args[1]);
case 3:
return $instance->$method($args[0], $args[1], $args[2]);
case 4:
return $instance->$method($args[0], $args[1], $args[2], $args[3]);
default:
return call_user_func_array(array($instance, $method), $args);
}
}
So the facade calls Illuminate\Validation\Validator
's non-static method validate()
.
I'm pretty sure this is accurate for 4.0 but please correct me if there any mistakes.