关于laravel:Laravel底层学习笔记03-make和build

7次阅读

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

参考资料:
php:laravel 底层外围代码剖析之 make 办法的实现
Laravel 加载过程 —make 办法

实例化 Illuminate\Contracts\Http\Kernel

make 办法

/public/index.php

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

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$app->make() => 父类 Application 中的 make() => resolve() 办法

resolve 办法

vendor/laravel/framework/src/Illuminate/Container/Container.php

/**
 * 第一次调用
 * $abstract Illuminate\Contracts\Http\Kernel::class
 * $concrete 匿名函数
 * 
 * 第二次调用
 * $abstract 'App\Http\Kernel'
 * $concrete 'App\Http\Kernel'(getConcrete 办法返回)* 执行 build() 办法获取 App\Http\Kernel 的实例化对象,返回给 getClosure()
 */
protected function resolve($abstract, $parameters = [], $raiseEvents = true)
{   
    ...
    // 依据 $abstract 从 bindings 数组中获取 $concrete 匿名函数
    $concrete = $this->getConcrete($abstract);
    // 判断 $concrete 和 $abstract 是否雷同,或者 $concrete 是一个匿名函数
    if ($this->isBuildable($concrete, $abstract)) {
        // 实例化 $concrete 的类
        $object = $this->build($concrete);
    } else {
        // 递归执行 make
        $object = $this->make($concrete);
    }
    ...
 }   

getClosure() 办法递归调用

/**
 * 第一次调用
 * $abstract 'Illuminate\Contracts\Http\Kernel'
 * $concrete 'App\Http\Kernel'
 * 
 * 第二次调用
 * 获取 App\Http\Kernel 的实例,向上返回给 build() 办法
 */
protected function getClosure($abstract, $concrete)
{return function ($container, $parameters = []) use ($abstract, $concrete) {if ($abstract == $concrete) {return $container->build($concrete);
        }
        return $container->resolve($concrete, $parameters, $raiseEvents = false);
    };
}

build 办法

vendor/laravel/framework/src/Illuminate/Container/Container.php

/**
 * 第一次调用
 * $concrete 匿名函数
 * 
 * 第二次调用
 * $concrete 'App\Http\Kernel' 
 * 执行反射,获取 App\Http\Kernel 类的实例化对象
 * 返回给 resolve() 办法
 */
public function build($concrete)
{if ($concrete instanceof Closure) {//bind() 办法中 $concrete = $this->getClosure($abstract, $concrete);
        return $concrete($this, $this->getLastParameterOverride());
    }
    $reflector = new ReflectionClass($concrete);
    if (! $reflector->isInstantiable()) {return $this->notInstantiable($concrete);
    }
    $this->buildStack[] = $concrete;
    $constructor = $reflector->getConstructor();
    if (is_null($constructor)) {array_pop($this->buildStack);
        return new $concrete;
    }
    $dependencies = $constructor->getParameters();
    $instances = $this->resolveDependencies($dependencies);
    array_pop($this->buildStack);
    return $reflector->newInstanceArgs($instances);
}
正文完
 0