09 07 2020

/public/index.php

// 入口文件
<?php
...
// 执行应用并响应
Container::get('app')->run()->send();


单例模式获取本类实例化,并调用make方法


/thinkphp/library/think/Container.php

<?php
...
/**
 * 获取容器中的对象实例
 * @access public
 * @param  string        $abstract       类名或者标识
 * @param  array|true    $vars           变量
 * @param  bool          $newInstance    是否每次创建新的实例
 * @return object
 */
public static function get($abstract, $vars = [], $newInstance = false)
{
    return static::getInstance()->make($abstract, $vars, $newInstance);
}

/**
 * 创建类的实例     
 * @access public     
 * @param  string        $abstract       类名或者标识     
 * @param  array|true    $vars           变量     
 * @param  bool          $newInstance    是否每次创建新的实例     
 * @return object     
 */
public function make($abstract, $vars = [], $newInstance = false)
{
    if (true === $vars) {
        // 总是创建新的实例化对象            
        $newInstance = true;
        $vars        = [];
    }

    // 第一次进来时 $this->name = []   $abstract = 'app'        
    // 第二次,$abstract = 'think\App' $this->name['think\App']还是不存在的        
    $abstract = isset($this->name[$abstract]) ? $this->name[$abstract] : $abstract;
    
    // 看下注册树中有没有,有的话直接返回注册树中的对象        
    if (isset($this->instances[$abstract]) && !$newInstance) {
        return $this->instances[$abstract];
    }

    // 第一次进来 $this->bind['app'] 是存在的        
    // 第二次进来 $this->bind['think\App']是不存在 直接走else        
    if (isset($this->bind[$abstract])) {
        $concrete = $this->bind[$abstract];
        // $concrete = "think\App";            
        if ($concrete instanceof Closure) { // think\App类不是闭包 走else                
            $object = $this->invokeFunction($concrete, $vars);
        } else {
            // 这时候把别名存入到name中 $this->name['app'] = think\App                
            $this->name[$abstract] = $concrete;
            // 再次调用make方法  $this->make('think\App', $var, $newInstance);                
            return $this->make($concrete, $vars, $newInstance);
        }
    } else {
        $object = $this->invokeClass($abstract, $vars); // 实例化App类        
    }

    if (!$newInstance) {
        // $this->instances['think\App'] = $object;            
        $this->instances[$abstract] = $object; // App类实例上树        
    }

    return $object;
}
...