31 05 2020

/thinkphp/library/think/Config.php

......

/**
 * 解析配置文件或内容
 * @access public
 * @param  string    $config 配置文件路径或内容
 * @param  string    $type 配置解析类型
 * @param  string    $name 配置名(如设置即表示二级配置)
 * @return mixed
 */
public function parse($config, $type = '', $name = '')
{
    if (empty($type)) {
        $type = pathinfo($config, PATHINFO_EXTENSION);
    }
    
    /*
     * 默认支持 ini、json、xml 后缀的配置文件
     * 如果以后多了其他后缀的配置文件,
     * 只需在 \\think\\config\\driver\\ 新增一个类(类名对应配置文件后缀名),并且实现parse() 解析规则方法
     */
    
    $object = Loader::factory($type, '\\think\\config\\driver\\', $config);
    
    // 获取到对象实例,调用 parse 方法
    return $this->set($object->parse(), $name);
}

......



/thinkphp/library/think/Loader.php

......

/**
 * 创建工厂对象实例
 * @access public
 * @param  string $name         工厂类名
 * @param  string $namespace    默认命名空间
 * @return mixed
 */
public static function factory($name, $namespace = '', ...$args)
{
    $class = false !== strpos($name, '\\') ? $name : $namespace . ucwords($name);

    if (class_exists($class)) {
        
        // 判断工厂类是否存在,获取工厂类的实例
        
        return Container::getInstance()->invokeClass($class, $args);
    } else {
        throw new ClassNotFoundException('class not exists:' . $class, $class);
    }
}

......



/thinkphp/library/think/Container.php

......

/**
 * 调用反射执行类的实例化 支持依赖注入
 * @access public
 * @param  string    $class 类名
 * @param  array     $vars  参数
 * @return mixed
 */
public function invokeClass($class, $vars = [])
{
    try {
    
        //ReflectionClass 类报告了一个类的有关信息。
        $reflect = new ReflectionClass($class);

        if ($reflect->hasMethod('__make')) {
            $method = new ReflectionMethod($class, '__make');

            if ($method->isPublic() && $method->isStatic()) {
                $args = $this->bindParams($method, $vars);
                return $method->invokeArgs(null, $args);
            }
        }
        
        // 获取类的构造函数
        $constructor = $reflect->getConstructor();
        
        $args = $constructor ? $this->bindParams($constructor, $vars) : [];

        // 创建一个类的新实例,给出的参数将传递到类的构造函数。
        // 这个参数以 array 形式传递到类的构造函数
        return $reflect->newInstanceArgs($args);

    } catch (ReflectionException $e) {
        throw new ClassNotFoundException('class not exists: ' . $class, $class);
    }
}

......