ITPub博客

首页 > IT职业 > IT生活 > 你知道Laravel的$this->app以及app()是怎么来的吗?

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

IT生活 作者:luckybird 时间:2021-09-11 09:35:08 0 删除 编辑
下面由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视频教程

以上就是你知道Laravel的$this->app以及app()是怎么来的吗?的详细内容,更多请关注php中文网其它相关文章!

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/1377/viewspace-2827564/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-04-15

  • 博文量
    113
  • 访问量
    1392