Laravel 静态绑定与容器原理

唔系我认叻

一、PHP中的静态绑定

“后期绑定”的意思是说,static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用。
<?php
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who(); // 后期静态绑定从这里开始
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test();//结果是 B
?>

说白了就是哪个类调用静态方法,该静态办法就属于哪个类下面。

二、Laravel中的静态绑定
laravel中用app() 可以实例化一个容器出来,然后这个容器是单一的,在里面操作laravel各种provider、event、等。代码跟踪看看其容器实现的原理;
先看app() 这个方法,helpers.php是入口文件中已经加载到框架里面;
\vendor\laravel\framework\src\Illuminate\Foundation\helpers.php

 function app($abstract = null, array $parameters = [])
    {
        if (is_null($abstract)) {
            return Container::getInstance();
        }

        return Container::getInstance()->make($abstract, $parameters);
    }

从上面代码看到主要是运行Container这个类的getInstance这个静态方法。

那我们从入口文件public/index.php跟踪,看下哪里有setInstance,

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

bootstrap/app.php

//实例化一个容器,这里就是LARAVEL的核心,用这个不断调用laravl内部
$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

\vendor\laravel\framework\src\Illuminate\Foundation\Application.php
先看继承关系

class Application extends Container implements ApplicationContract, CachesConfiguration, CachesRoutes, HttpKernelInterface

然后构造函数

public function __construct($basePath = null)
    {
        if ($basePath) {
            $this->setBasePath($basePath);
        }

        $this->registerBaseBindings();
        $this->registerBaseServiceProviders();
        $this->registerCoreContainerAliases();
    }

基本绑定$this->registerBaseBindings();

protected function registerBaseBindings()
    {
        static::setInstance($this);//父类静态方法,这里的父类是Container

        $this->instance('app', $this);

        $this->instance(Container::class, $this);
        $this->singleton(Mix::class);

        $this->singleton(PackageManifest::class, function () {
            return new PackageManifest(
                new Filesystem, $this->basePath(), $this->getCachedPackagesPath()
            );
        });
    }

查看vendor\laravel\framework\src\Illuminate\Container\Container.php

 public static function setInstance(ContainerContract $container = null)
    {
        return static::$instance = $container;
    }

看到这里,在这个文件中再看看getInstance这个方法

 public static function getInstance()
    {
        if (is_null(static::$instance)) {
            static::$instance = new static;//实例化application
        }

        return static::$instance;
    }

从这里就完成了整个laravl的容器实例化过程。主要是靠静态绑定的方法,实力化application。

阅读 164
1 声望
0 粉丝
0 条评论
1 声望
0 粉丝
文章目录
宣传栏