一、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。
发表回复