斷點調試尋找對應文件,忽略次要步驟,僅描述核心動作,‘/’表示index.php所在目錄
地址:index.php
$app = require_once __DIR__.'/../bootstrap/app.php';
$app初始化
路徑/…/bootstrap/app.php
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);//$app初始化工作
$app初始化的類及構造函數
class Application extends Container implements ApplicationContract,HttpKernelInterface
{
//繼承Container類,Container類實現應用契約接口與請求接口
public function __construct($basePath = null){
if ($basePath) {//$basePath = '/../'
$this->setBasePath($basePath);//路徑綁定
}
$this->registerBaseBindings();//基礎綁定
$this->registerBaseServiceProviders();//註冊基礎服務提供者
$this->registerCoreContainerAliases();//註冊別名
}
}
路徑綁定
Application的setBasePath(’/…/’)方法調用Container的instance(a b s t r a c t , abstract,abstract,instance)方法賦值Contaienr類instances
instances: array:9 [▼
“path” => “\var\www\app”
“path.base” => “\var\www”
“path.lang” => “\var\www\resources\lang”
“path.config” => “\var\www\config”
“path.public” => “\var\www\public”
“path.storage” => “\var\www\storage”
“path.database” => “\var\www\database”
“path.resources” => “\var\www\resources”
“path.bootstrap” => “\var\www\bootstrap”
]
基礎綁定
向Container的instances中添加綁定
"app" => Application {#2}
"Illuminate\Container\Container" => Application {#2}
"Illuminate\Foundation\PackageManifest" => PackageManifest {#4 ▼
+files: Filesystem {#5}
+basePath: "\var\www"
+vendorPath: "\var\www\vendor"
+manifestPath: "\var\www\bootstrap\cache\packages.php"
+manifest: null
}
app與Container指向當前實例
PackageMainfest 爲包管理實例,構造方法中files註冊文件系統實例
註冊基礎服務提供者
//class Application
protected function registerBaseServiceProviders()
{
$this->register(new EventServiceProvider($this));
$this->register(new LogServiceProvider($this));
$this->register(new RoutingServiceProvider($this));
}
Event、Log、Routing基礎服務繼承ServiceProvider,初始化的時候將app屬性賦值Application實例
//class ServiceProvider
public function __construct($app)
{
$this->app = $app;
}
執行Application類register方法
//Application
public function register($provider, $options = [], $force = false)
{
if (is_string($provider)) {
$provider = $this->resolveProvider($provider);
}
if (method_exists($provider, 'register')) {
$provider->register();//賦值bindings
}
//將服務提供者添加到serviceProviders屬性隊列
//將服務提供者類名添加到loaderProviders屬性
$this->markAsRegistered($provider);
return $provider;
}
爲provider註冊提供了兩種方法;
一種是字符串類名直接實例,
一種是執行$$provider->register()方法註冊,
當前執行第二種方法,
回看當前EventServiceProvider實例的register方法
public function register()
{
$this->app->singleton('events', function ($app) {
return (new Dispatcher($app))->setQueueResolver(function () use ($app) {
return $app->make(QueueFactoryContract::class);
});
});
}
調用Application實例的singleton方法
//class Continer
public function singleton($abstract, $concrete = null)
{
$this->bind($abstract, $concrete, true);
}
調用bind方法,賦值bindings
//class Container
public function bind($abstract, $concrete = null, $shared = false)
{
if (is_null($concrete)) {
$concrete = $abstract;
}
if (! $concrete instanceof Closure) {
$concrete = $this->getClosure($abstract, $concrete);
}
$this->bindings[$abstract] = compact('concrete', 'shared');
}
回到Application類register方法中並執行markAsRegistered($provider)
//class Application
protected function markAsRegistered($provider)
{
$this->serviceProviders[] = $provider;
$this->loadedProviders[get_class($provider)] = true;
}
LogServerProvider、RoutingServiceProvider與之類似
別名綁定
//class Application
public function registerCoreContainerAliases()
{
foreach ([
'app' => [self::class, \Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class, \Psr\Container\ContainerInterface::class],
'auth' => [\Illuminate\Auth\AuthManager::class, \Illuminate\Contracts\Auth\Factory::class],
'auth.driver' => [\Illuminate\Contracts\Auth\Guard::class],
'blade.compiler' => [\Illuminate\View\Compilers\BladeCompiler::class],
'cache' => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class],
'cache.store' => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class],
'config' => [\Illuminate\Config\Repository::class, \Illuminate\Contracts\Config\Repository::class],
'cookie' => [\Illuminate\Cookie\CookieJar::class, \Illuminate\Contracts\Cookie\Factory::class, \Illuminate\Contracts\Cookie\QueueingFactory::class],
'encrypter' => [\Illuminate\Encryption\Encrypter::class, \Illuminate\Contracts\Encryption\Encrypter::class],
'db' => [\Illuminate\Database\DatabaseManager::class],
'db.connection' => [\Illuminate\Database\Connection::class, \Illuminate\Database\ConnectionInterface::class],
'events' => [\Illuminate\Events\Dispatcher::class, \Illuminate\Contracts\Events\Dispatcher::class],
'files' => [\Illuminate\Filesystem\Filesystem::class],
'filesystem' => [\Illuminate\Filesystem\FilesystemManager::class, \Illuminate\Contracts\Filesystem\Factory::class],
'filesystem.disk' => [\Illuminate\Contracts\Filesystem\Filesystem::class],
'filesystem.cloud' => [\Illuminate\Contracts\Filesystem\Cloud::class],
'hash' => [\Illuminate\Contracts\Hashing\Hasher::class],
'translator' => [\Illuminate\Translation\Translator::class, \Illuminate\Contracts\Translation\Translator::class],
'log' => [\Illuminate\Log\Writer::class, \Illuminate\Contracts\Logging\Log::class, \Psr\Log\LoggerInterface::class],
'mailer' => [\Illuminate\Mail\Mailer::class, \Illuminate\Contracts\Mail\Mailer::class, \Illuminate\Contracts\Mail\MailQueue::class],
'auth.password' => [\Illuminate\Auth\Passwords\PasswordBrokerManager::class, \Illuminate\Contracts\Auth\PasswordBrokerFactory::class],
'auth.password.broker' => [\Illuminate\Auth\Passwords\PasswordBroker::class, \Illuminate\Contracts\Auth\PasswordBroker::class],
'queue' => [\Illuminate\Queue\QueueManager::class, \Illuminate\Contracts\Queue\Factory::class, \Illuminate\Contracts\Queue\Monitor::class],
'queue.connection' => [\Illuminate\Contracts\Queue\Queue::class],
'queue.failer' => [\Illuminate\Queue\Failed\FailedJobProviderInterface::class],
'redirect' => [\Illuminate\Routing\Redirector::class],
'redis' => [\Illuminate\Redis\RedisManager::class, \Illuminate\Contracts\Redis\Factory::class],
'request' => [\Illuminate\Http\Request::class, \Symfony\Component\HttpFoundation\Request::class],
'router' => [\Illuminate\Routing\Router::class, \Illuminate\Contracts\Routing\Registrar::class, \Illuminate\Contracts\Routing\BindingRegistrar::class],
'session' => [\Illuminate\Session\SessionManager::class],
'session.store' => [\Illuminate\Session\Store::class, \Illuminate\Contracts\Session\Session::class],
'url' => [\Illuminate\Routing\UrlGenerator::class, \Illuminate\Contracts\Routing\UrlGenerator::class],
'validator' => [\Illuminate\Validation\Factory::class, \Illuminate\Contracts\Validation\Factory::class],
'view' => [\Illuminate\View\Factory::class, \Illuminate\Contracts\View\Factory::class],
] as $key => $aliases) {
foreach ($aliases as $alias) {
$this->alias($key, $alias);
}
}
}
爲alias屬性賦值
$app核心類綁定
/…/bootstrap/app.php
/**
*核心類綁定
*/
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
調用bind函數
//class Container
public function singleton($abstract, $concrete = null)
{
$this->bind($abstract, $concrete, true);
}
對字符串類名進行默認回調函數綁定
//class Container
public function bind($abstract, $concrete = null, $shared = false)
{
// If the factory is not a Closure, it means it is just a class name which is
// bound into this container to the abstract type and we will just wrap it
// up inside its own Closure to give us more convenience when extending.
if (! $concrete instanceof Closure) {
$concrete = $this->getClosure($abstract, $concrete);
}
$this->bindings[$abstract] = compact('concrete', 'shared');
}
getClosure返回默認回調函數
//class Container
protected function getClosure($abstract, $concrete)
{
return function ($container, $parameters = []) use ($abstract, $concrete) {
if ($abstract == $concrete) {
return $container->build($concrete);
}
return $container->make($concrete, $parameters);
};
}
最終:返回$app
/…/bootstrap/app.php
return $app;