我也想知道这个问题的答案,但我决定自己去找。
如果你去app/storage/meta
那里有一个services.json
列出eager
和deferred
类。这样我们就不会为每个请求加载所有类,因为Form
如果我们正在构建 API,我们可能永远不需要该类。
该类ProviderRepository
扫描列出的所有提供程序app/config/app.php
并为每个提供程序实例化(这些不是实际的库)。
CacheServiceProvider
例如,这些提供程序Illuminate/Cache
有一个名为的变量,该变量defer
确定库是否将被急切加载或延迟到需要时加载。
这是一个引述ProviderRepository
重新编译服务清单时,我们将遍历每个提供程序并检查它是否是延迟提供程序。如果是这样,我们会将其提供的服务添加到清单中并记下提供者。
对于CacheServiceProvider
this 设置为true
.
所以可以说Validator::make()
这里被称为是我收集到的;Facade
诸如门面之类的每一个都Validator
扩展了.Facade
Illuminate\Support\Facades\Facade
这有一个神奇的方法__callStatic($method, $args)
,非常不言自明,这个方法的要点是
$instance = static::resolveFacadeInstance(static::getFacadeAccessor());
在这种情况下,外观访问器返回执行验证的实际类的字符串 ( Illuminate\Validation\Validator
):
protected static function getFacadeAccessor() { return 'validator'; }
main 方法resolveFacadeInstance
检查返回的访问器是否为对象。如果是,它只是简单地返回它,因为它可能是一个自定义的 Laravel 包。
这个方法的第二部分检查它是否已经被解析,如果它已经返回。最后一部分:
return static::$resolvedInstance[$name] = static::$app[$name];
通过位于前面提到的父类中的数组访问接口调用Illuminate\Foundation\Application
(扩展Illuminate\Container\Container
类) 。
所以static::$app[$name]
调用:
public function offsetGet($key)
{
return $this->make($key);
}
这位于Container
类
这将我们引向类中的make()
方法Application
:
public function make($abstract, $parameters = array())
{
if (isset($this->deferredServices[$abstract]))
{
$this->loadDeferredProvider($abstract);
}
return parent::make($abstract, $parameters);
}
我将让您深入研究该parent::make()
方法,因为这将开始变得非常冗长,但就目前而言,这是加载延迟提供程序并通过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();
}
代码块中的注释应该解释其余发生的事情。
从这里开始,最后一部分__callStatic($method, $args)
触发名为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);
}
}
所以门面调用Illuminate\Validation\Validator
的非静态方法validate()
。
我很确定这对于 4.0 是准确的,但如果有任何错误,请纠正我。