关于php:Laravel-静态绑定与容器原理

29次阅读

共计 2084 个字符,预计需要花费 6 分钟才能阅读完成。

一、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。

正文完
 0