Jul*_*ian 6 php laravel-5 laravel-5.2
我有以下定义:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\SomeClass;
class SomeProvider extends ServiceProvider
{
protected $defer = true;
public function register()
{
$this->app->bind(SomeClass::class, function ($app)
{
return new SomeClass();
});
}
public function provides()
{
die("This never gets called");
return [SomeClass::class];
}
}
Run Code Online (Sandbox Code Playgroud)
并且它SomeClass按预期返回一个实例,除了根据文档,如果$defer为真,provides()则应调用该方法。无论我设置什么$defer,也无论我是否真的要求一个实例SomeClass,provides()都不会被调用。
我要求类的实例的方式如下:
App::make('SomeClass');
Run Code Online (Sandbox Code Playgroud)
简短回答:
您编译的清单文件已经由框架编译。
当 Laravel 第一次构建应用程序(并解析 IoC 容器中的所有服务提供者)时,它会写入名为services.php 的缓存文件(即清单文件,放在: 中bootstrap/cache/services.php)。
因此,如果您清除通过php artisan clear-compiled命令编译的内容,它应该强制框架重建清单文件,您可能会注意到provides调用了该方法。在下一个调用/请求provides方法不再被调用。
框架启动的顺序几乎是这样的:
//public/index.php
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
\Illuminate\Foundation\Http\Kernel::__construct();
\Illuminate\Foundation\Http\Kernel::handle();
\Illuminate\Foundation\Http\Kernel::sendRequestThroughRouter();
\Illuminate\Foundation\Http\Kernel::bootstrap();
\Illuminate\Foundation\Application::bootstrapWith();
# where $bootstrapper is a item from \Illuminate\Foundation\Http\Kernel::$bootstrappers
# and $this is instance of \Illuminate\Foundation\Application
\Illuminate\Foundation\Application::make($bootstrapper)->bootstrap($this);
Run Code Online (Sandbox Code Playgroud)
引导程序之一是Illuminate\Foundation\Bootstrap\RegisterProviders调用\Illuminate\Foundation\Application::registerConfiguredProviders(),然后调用
\Illuminate\Foundation\ProviderRepository::__construct(),最后:
\Illuminate\Foundation\ProviderRepository::load()
当\Illuminate\Foundation\ProviderRepository::load()被调用时,所有服务提供者\Illuminate\Support\ServiceProvider::provides()都已注册并且
也被很好地调用。
这是您应该知道的片段(来自\Illuminate\Foundation\ProviderRepository::load):
/**
* Register the application service providers.
*
* @param array $providers
* @return void
*/
public function load(array $providers)
{
$manifest = $this->loadManifest();
// First we will load the service manifest, which contains information on all
// service providers registered with the application and which services it
// provides. This is used to know which services are "deferred" loaders.
if ($this->shouldRecompile($manifest, $providers)) {
$manifest = $this->compileManifest($providers);
}
// Next, we will register events to load the providers for each of the events
// that it has requested. This allows the service provider to defer itself
// while still getting automatically loaded when a certain event occurs.
foreach ($manifest['when'] as $provider => $events) {
$this->registerLoadEvents($provider, $events);
}
// We will go ahead and register all of the eagerly loaded providers with the
// application so their services can be registered with the application as
// a provided service. Then we will set the deferred service list on it.
foreach ($manifest['eager'] as $provider) {
$this->app->register($this->createProvider($provider));
}
$this->app->addDeferredServices($manifest['deferred']);
}
Run Code Online (Sandbox Code Playgroud)
\Illuminate\Foundation\ProviderRepository::compileManifest()provides()是执行您的方法的地方。
| 归档时间: |
|
| 查看次数: |
3856 次 |
| 最近记录: |