我需要深刻理解laravel。自从我们开始使用laravel以来,我必须向开发团队解释一切。
如果错误,请更正此问题:当laravel启动时,由于性能提升,它将服务提供商拆分为'eager'和'deferred',然后注册所有'eager'提供商,但不会'延期'。
我的问题: 每次我们使用延期服务,例如:
$validator = Validator::make(
//..
);
laravel如何加载并注册该类/服务?我发现这可能与Illuminate\Foundation\ProviderRepository
Class
$app->setDeferredServices($manifest['deferred']);
然后我卡住了。抱歉英语不好,希望大家都明白。感谢。
答案 0 :(得分:14)
我也想知道答案,但我决定自己寻找。
如果您转到app/storage/meta
,则services.json
会列出eager
和deferred
类。这样我们就不会为每个请求加载所有类,因为如果我们构建API,我们可能永远不需要Form
类。
ProviderRepository
类扫描app/config/app.php
中列出的所有提供程序,并为每个提供程序实例化提供程序(这些不是实际的库)。
这些提供程序(例如CacheServiceProvider
中的Illuminate/Cache
有一个名为defer
的变量,用于确定在需要之前是否会急切地加载库。
以下是ProviderRepository
重新编译服务清单时,我们将遍历每个服务清单 提供者并检查它是否是延迟提供者。如果是这样 我们将为清单添加它提供的服务并注意 提供商。
对于CacheServiceProvider
,此设置为true
。
所以我想在这里调用Validator::make()
是我所收集的内容;每个Facade
(例如Validator
外观)都会扩展Facade
中的基础Illuminate\Support\Facades\Facade
类。
这有一个神奇的方法__callStatic($method, $args)
这是非常自我解释的,这个方法的要点是
$instance = static::resolveFacadeInstance(static::getFacadeAccessor());
在这种情况下,facade门户访问器返回执行验证的实际类的字符串(Illuminate\Validation\Validator
):
protected static function getFacadeAccessor() { return 'validator'; }
主方法resolveFacadeInstance
检查返回的访问者是否是对象。如果它只是返回它,因为它可能是一个自定义的Laravel包。
此方法的第二部分检查它是否已经解析,如果已经解决了。最后一部分:
return static::$resolvedInstance[$name] = static::$app[$name];
通过位于前面提到的父类中的array access接口调用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是准确的,但如果有任何错误,请纠正我。