1. 类路径
tp5\thinkphp\library\think\Config.php
2. 父类 \ArrayAccess
实现父类的方法,可以像访问数组一样访问对象
3. 配置文件加载
public function load($file, $name = '')
{
//如果是文件
if (is_file($file)) {
$filename = $file;
} elseif (is_file($this->path . $file . $this->ext)) {
//如果拼接成的是文件
$filename = $this->path . $file . $this->ext;
}
//如果有这个文件
if (isset($filename)) {
//加载这个文件
return $this->loadFile($filename, $name);
} elseif ($this->yaconf && Yaconf::has($file)) {
//获取yaconf内配置内存,存入类中
return $this->set(Yaconf::get($file), $name);
}
return $this->config;
}
4. 文件加载
protected function loadFile($file, $name)
{
//配置名小写
$name = strtolower($name);
//文件类型
$type = pathinfo($file, PATHINFO_EXTENSION);
//如果是php 直接inclue加载文件内容, 设置到$this->config中
if ('php' == $type) {
return $this->set(include $file, $name);
} elseif ('yaml' == $type && function_exists('yaml_parse_file')) {
//如果是yaml类型
return $this->set(yaml_parse_file($file), $name);
}
//其他类型,解析文件内容
return $this->parse($file, $type, $name);
}
5. 解析配置文件
public function parse($config, $type = '', $name = '')
{
//如果类型为空,则取文件后缀名
if (empty($type)) {
$type = pathinfo($config, PATHINFO_EXTENSION);
}
//工厂模式生成 对应文件的解析类
$object = Loader::factory($type, '\\think\\config\\driver\\', $config);
//用对应文件解析类的parse方法解析文件内容,将解析出的配置设置到$this->config中
return $this->set($object->parse(), $name);
}
6. 工厂类
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);
}
}
7. 如果类型为ini, ini解析的类
<?php
namespace think\config\driver;
class Ini
{
protected $config;
//实例时,存储要解析的文件路径或内容
public function __construct($config)
{
$this->config = $config;
}
public function parse()
{
//解析出配置内容
if (is_file($this->config)) {
return parse_ini_file($this->config, true);
} else {
return parse_ini_string($this->config, true);
}
}
}
8. Config类的配置设置
public function set($name, $value = null)
{
//如果是字符串类型
if (is_string($name)) {
//如果没有 .
if (false === strpos($name, '.')) {
//拼接前缀
$name = $this->prefix . '.' . $name;
}
//用点切割字符串
$name = explode('.', $name, 3);
if (count($name) == 2) {
//如果是两级, 配置内容设置到数组中
$this->config[strtolower($name[0])][$name[1]] = $value;
} else {
//最多支持3级
$this->config[strtolower($name[0])][$name[1]][$name[2]] = $value;
}
return $value;
} elseif (is_array($name)) {
//如果是数组
// 批量设置
//如果传入了key, 则将数组的配置设置到特定的key上
if (!empty($value)) {
if (isset($this->config[$value])) {
$result = array_merge($this->config[$value], $name);
} else {
$result = $name;
}
$this->config[$value] = $result;
} else {
//没有传入可定的key,进行配置合并,如果有重复的配置,新传入的配置会覆盖掉已有的
$result = $this->config = array_merge($this->config, $name);
}
} else {
// 为空直接返回 已有配置
$result = $this->config;
}
return $result;
}