下面给大家介绍Laravel的$this->app以及app()是怎么来的,希望对需要的朋友有所帮助!
断点调试寻找对应文件,忽略次要步骤,仅描述核心动作,‘/’表示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 Applicationprotected 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方法
//Applicationpublic 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 Continerpublic function singleton($abstract, $concrete = null){ $this->bind($abstract, $concrete, true);}调用bind方法,赋值bindings
//class Containerpublic 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 Applicationprotected function markAsRegistered($provider){ $this->serviceProviders[] = $provider; $this->loadedProviders[get_class($provider)] = true;}LogServerProvider、RoutingServiceProvider与之类似
别名绑定
//class Applicationpublic 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' 

