你知道Laravel的$this->app以及app()是怎么来的吗?

下面由laravel教程栏目给大家介绍laravel的$this->app以及app()是怎么来的,希望对需要的朋友有所帮助!

断点调试寻找对应文件,忽略次要步骤,仅描述核心动作,‘/’表示index.php所在目录

地址:index.php

$app = require_once __DIR__.'/../bootstrap/app.php';

$app初始化

路径/…/bootstrap/app.php

$app = new IlluminateFoundationApplication(     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” => “varwwwapp” “path.base” => “varwww” “path.lang” => “varwwwresourceslang” “path.config” => “varwwwconfig” “path.public” => “varwwwpublic” “path.storage” => “varwwwstorage” “path.database” => “varwwwdatabase” “path.resources” => “varwwwresources” “path.bootstrap” => “varwwwbootstrap” ]

基础绑定

  向Container的instances中添加绑定

    "app" => Application {#2}       "IlluminateContainerContainer" => Application {#2}       "IlluminateFoundationPackageManifest" => PackageManifest {#4 ▼             +files: Filesystem {#5}             +basePath: "varwww"             +vendorPath: "varwwwvendor"             +manifestPath: "varwwwbootstrapcachepackages.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, IlluminateContractsContainerContainer::class, IlluminateContractsFoundationApplication::class,  PsrContainerContainerInterface::class],         'auth'                 => [IlluminateAuthAuthManager::class, IlluminateContractsAuthFactory::class],         'auth.driver'          => [IlluminateContractsAuthGuard::class],         'blade.compiler'       => [IlluminateViewCompilersBladeCompiler::class],         'cache'                => [IlluminateCacheCacheManager::class, IlluminateContractsCacheFactory::class],         'cache.store'          => [IlluminateCacheRepository::class, IlluminateContractsCacheRepository::class],         'config'               => [IlluminateConfigRepository::class, IlluminateContractsConfigRepository::class],         'cookie'               => [IlluminateCookieCookieJar::class, IlluminateContractsCookieFactory::class, IlluminateContractsCookieQueueingFactory::class],         'encrypter'            => [IlluminateEncryptionEncrypter::class, IlluminateContractsEncryptionEncrypter::class],         'db'                   => [IlluminateDatabaseDatabaseManager::class],         'db.connection'        => [IlluminateDatabaseConnection::class, IlluminateDatabaseConnectionInterface::class],         'events'               => [IlluminateEventsDispatcher::class, IlluminateContractsEventsDispatcher::class],         'files'                => [IlluminateFilesystemFilesystem::class],         'filesystem'           => [IlluminateFilesystemFilesystemManager::class, IlluminateContractsFilesystemFactory::class],         'filesystem.disk'      => [IlluminateContractsFilesystemFilesystem::class],         'filesystem.cloud'     => [IlluminateContractsFilesystemCloud::class],         'hash'                 => [IlluminateContractsHashingHasher::class],         'translator'           => [IlluminateTranslationTranslator::class, IlluminateContractsTranslationTranslator::class],         'log'                  => [IlluminateLogWriter::class, IlluminateContractsLoggingLog::class, PsrLogLoggerInterface::class],         'mailer'               => [IlluminateMailMailer::class, IlluminateContractsMailMailer::class, IlluminateContractsMailMailQueue::class],         'auth.password'        => [IlluminateAuthPasswordsPasswordBrokerManager::class, IlluminateContractsAuthPasswordBrokerFactory::class],         'auth.password.broker' => [IlluminateAuthPasswordsPasswordBroker::class, IlluminateContractsAuthPasswordBroker::class],         'queue'                => [IlluminateQueueQueueManager::class, IlluminateContractsQueueFactory::class, IlluminateContractsQueueMonitor::class],         'queue.connection'     => [IlluminateContractsQueueQueue::class],         'queue.failer'         => [IlluminateQueueFailedFailedJobProviderInterface::class],         'redirect'             => [IlluminateRoutingRedirector::class],         'redis'                => [IlluminateRedisRedisManager::class, IlluminateContractsRedisFactory::class],         'request'              => [IlluminateHttpRequest::class, SymfonyComponentHttpFoundationRequest::class],         'router'               => [IlluminateRoutingRouter::class, IlluminateContractsRoutingRegistrar::class, IlluminateContractsRoutingBindingRegistrar::class],         'session'              => [IlluminateSessionSessionManager::class],         'session.store'        => [IlluminateSessionStore::class, IlluminateContractsSessionSession::class],         'url'                  => [IlluminateRoutingUrlGenerator::class, IlluminateContractsRoutingUrlGenerator::class],         'validator'            => [IlluminateValidationFactory::class, IlluminateContractsValidationFactory::class],         'view'                 => [IlluminateViewFactory::class, IlluminateContractsViewFactory::class],     ] as $key => $aliases) {         foreach ($aliases as $alias) {             $this->alias($key, $alias);         }     } }

为alias属性赋值

$app核心类绑定

/…/bootstrap/app.php /**  *核心类绑定  */ $app->singleton(     IlluminateContractsHttpKernel::class,     AppHttpKernel::class ); $app->singleton(     IlluminateContractsConsoleKernel::class,     AppConsoleKernel::class ); $app->singleton(     IlluminateContractsDebugExceptionHandler::class,     AppExceptionsHandler::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;

相关推荐:最新的五个laravel视频教程

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享