我是靠谱客的博主 唠叨热狗,最近开发中收集的这篇文章主要介绍thinkphp5.1 config类和env类源码剖析 set方法简要分为4个场景:总结:在APP类执行初始化加载配置时,主要用到了第一和第二个场景看完set方法,再看到get方法的场景:4.正常获取配置get和set方法均已讲解完毕,目光看到load方法:ENV类刨析查看load,set两个函数代码可知,.env的配置内容 : CONFIG_EXT= .PHP(或者其他后缀,一旦指定后缀,只能加载指定后缀的配置文件)调试代码的方法:,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
此章节带领读者来一起阅读config类和env类,这两个类是tp5.1加载配置的核心类,看懂了这两个类以后,再结合app类初始化部分,tp5.1的配置加载规则将一目了然。
此博客专门介绍这两个类,后续有专门的博客专门介绍tp5.1配置的加载,不过为了更好理解代码,这里也会插入。
config类代码刨析:
(一)主要成员属性以及构造方法
config类是由app容器类加载的,app继承了container类,因此读过容器部分的代码就知道,当config实例化的时候,调用__make函数,将app类中赋值的属性$this->configPath以及$this->configExt注入进config,作为config类初始化的值。相关代码:
先解释下这个函数是干什么的:这段函数就是入口文件执行的run方法的最开头部分:
然后,app类先初始化自己,这样$this->configPath以及$this->configExt就初始化好了,当调用不存在的成员变量:$this->config时就会去实例化config类,并将$this->configPath以及$this->configExt两个属性注入config,初始化config.
初始化完成后,config类最核心的函数以及它的作用如图:
ArrayAccess我在容器的文章讲解了,这里不过多阐述。主要核心函数由图可知。
我们先看set方法:
/**
* 设置配置参数 name为数组则为批量设置
* @access public
* @param string|array $name 配置参数名(支持三级配置 .号分割) 如 配置文件名.键值.下级键值一共三级,支持到二维数组
* @param mixed $value 配置值
* @return mixed
*/
public function set($name, $value = null)
{
if (is_string($name)) {
if (false === strpos($name, '.')) {
$name = $this->prefix . '.' . $name;
}
$name = explode('.', $name, 3); //e.g. app.debug
if (count($name) == 2) { //e.g. $this->config['app']['debug'] = xxx
$this->config[strtolower($name[0])][$name[1]] = $value;
} else { //e.g. $this->config['app']['debug']['xxxx'] = xxx
$this->config[strtolower($name[0])][$name[1]][$name[2]] = $value;
}
return $value;
} elseif (is_array($name)) {
// 批量设置
if (!empty($value)) {
if (isset($this->config[$value])) {
$result = array_merge($this->config[$value], $name); //将同属于app配置文件的配置归类于$this->config['app']下,其他文件的配置也是如此分类
} else {
$result = $name;
}
$this->config[$value] = $result; //将同属于app配置文件的配置归类于$this->config['app']下,其他文件的配置也是如此分类
} else {
$result = $this->config = array_merge($this->config, $name); //$this->config->set(include $this->thinkPath . 'convention.php');没有传value,直接将配置文件返回的数组合并
}
} else {
// 为空直接返回 已有配置
$result = $this->config;
}
return $result;
}
set方法简要分为4个场景:
1.初始化惯例配置的时候使用的set方法。这个场景在APP类initialize()方法中,代码如下:
走到此处:
2.读取配置文件,配置文件所返回的数组走到第二大分支的逻辑 is_array($name) ,该场景和第一点一样,是同样的逻辑分支,但它执行的地方是此处:
3.当$name是字符时,则直接设置。如果不是以xx.xx的形式传入,只有一个name值,则默认加上app前缀,意思是默认给app配置文件添加配置。对应代码:
.e.g 当传入的参数是$name = 'app.name' 和 $value = 'xxxx' 时,则设置,$this->config['app']['debug'] = xxxx; 由$name = explode('.', $name, 3); 语句可知,
最多只能支持设置三维数组。比如:$this->config['app']['debug']['xxx'] = xxxx;
PS:$this->config['app']['debug']['xxx']数组中存在这样的对应关系,第一维的键对应相应的配置文件,比如 $this->config['app']对应app.php的配置文件。
接下来后面的二维或者到三维数组的元素是该文件下的配置。比如:$this->config['app']['debug']['xxx'] 中的['debug']['xxx']是app.php配置文件的某项配置。
所有配置会按照这种形式,以第一维的键对应配置的文件名,归类并对应到各自的文件名键中去,保存在$this->config中。
4.最后一个逻辑分支:$name为空时,返回$this->config.
总结:在APP类执行初始化加载配置时,主要用到了第一和第二个场景
看完set方法,再看到get方法的场景:
代码:
1.没有指定配置文件。
.e.g 比如:app.debug ,你不写app,只写了debug,则函数默认给你加上app,意思是该配置默认为app.xxx
2.无参数时,将获取所有保存在属性config中的配置
3.获取某配置文件下所有的配置
.e.g 当输入$name为'app.' ,如果你的获取是这样写的就会执行这一段代码,substr($name, 0, -1)=>将最后的.去掉,比如app. 就变成 app.此时执行pull函数
/**
* 获取一级配置
* @access public
* @param string $name 一级配置名
* @return array
*/
public function pull($name)
{
$name = strtolower($name);
if ($this->yaconf) { //如果yaconf开启
$yaconfName = $this->getYaconfName($name);
if (Yaconf::has($yaconfName)) {
$config = Yaconf::get($yaconfName);
return isset($this->config[$name]) ? array_merge($this->config[$name], $config) : $config; //假设name是app,如果yaconf的app有数据,就会把$this->config['app']的东西和yaconf合并返回(相同键的元素,yaconf会覆盖,优先级高)
}
}
return isset($this->config[$name]) ? $this->config[$name] : []; //假设name是app,直接返回$this->config['app']的内容
}
ps:如果开启了yaconf,则会将yaconf的内容和当前的的配置合并,相同元素以yaconf为准. 否则,返回config属性所保存的配置
4.正常获取配置
.e.g 传入app.debug,就返回app配置文件下debug的配置
get和set方法均已讲解完毕,目光看到load方法:
这段代码关联到app类的init()方法:
根据app执行时,config类去加载app类决定执行的对应后缀的配置文件。因此,这里便使用到工厂模式,以用来加载和app类执行的相应后缀的配置文件。
protected function loadFile($file, $name)
{
$name = strtolower($name);
$type = pathinfo($file, PATHINFO_EXTENSION); //$type是返回配置文件后缀信息
if ('php' == $type) {
return $this->set(include $file, $name);
} elseif ('yaml' == $type && function_exists('yaml_parse_file')) {
return $this->set(yaml_parse_file($file), $name);
}
return $this->parse($file, $type, $name);
}
/**
* 解析配置文件或内容
* @access public
* @param string $config 配置文件路径或内容 ,例如这样的 E:phpstudy_proWWWtp5.1configdatabase.php
* @param string $type 配置解析类型
* @param string $name 配置名(如设置即表示二级配置)
* @return mixed
*/
public function parse($config, $type = '', $name = '')
{
if (empty($type)) {
$type = pathinfo($config, PATHINFO_EXTENSION);
}
//工厂模式
$object = Loader::factory($type, '\think\config\driver\', $config);
return $this->set($object->parse(), $name);
}
工厂的代码内容,可以阅读容器的章节,属于容器创建对象的内容。
总结:config类核心功能可以看前面的图即可。
ENV类刨析
env类核心有这几个类:
/**
* 读取环境变量定义文件
* @access public
* @param string $file 环境变量定义文件
* @return void
*/
public function load($file)
{
$env = parse_ini_file($file, true);
$this->set($env);
}
/**
* 获取环境变量值
* @access public
* @param string $name 环境变量名
* @param mixed $default 默认值
* @return mixed
*/
public function get($name = null, $default = null, $php_prefix = true)
{
//没有指定配置时,全部返回
if (is_null($name)) {
return $this->data;
}
$name = strtoupper(str_replace('.', '_', $name));
if (isset($this->data[$name])) { //var_dump($this->data);
return $this->data[$name];
}
// echo $name;echo "n";
// var_dump($this->getEnv($name, $default, $php_prefix));
//若data数组没有,则去系统变量中看看有无数据
return $this->getEnv($name, $default, $php_prefix);
}
//获取系统的环境变量,分php的系统变量或者其他变量
protected function getEnv($name, $default = null, $php_prefix = true)
{
if ($php_prefix) {
$name = 'PHP_' . $name;
}
//内置函数,获取系统环境变量
$result = getenv($name); // var_dump($result);
//返回默认的配置
if (false === $result) {
return $default;
}
if ('false' === $result) {
$result = false;
} elseif ('true' === $result) {
$result = true;
}
//系统变量,如果data没保存,则注册到data
if (!isset($this->data[$name])) {
$this->data[$name] = $result;
}
return $result;
}
/**
* 设置环境变量值
* @access public
* @param string|array $env 环境变量
* @param mixed $value 值
* @return void
*/
public function set($env, $value = null) //先分析功能,再分析使用场景
{
if (is_array($env)) {
$env = array_change_key_case($env, CASE_UPPER); //将所有配置数组的键转为大写
//this->data 的键值对,THINK_PATH => E:phpstudy_proWWWtp5.1thinkphp 它的格式统一的 so on
foreach ($env as $key => $val) {
if (is_array($val)) {
foreach ($val as $k => $v) {
$this->data[$key . '_' . strtoupper($k)] = $v; //例如:[APP=>['path'=>'xxxx']],形成格式一样是,两个大写的单词用下划线拼接。它的格式是统一的,同上的键值对形式 THINK_PATH => E:phpstudy_proWWWtp5.1thinkphp
}
} else {
$this->data[$key] = $val; //将env的东西保存到data,THINK_PATH => E:phpstudy_proWWWtp5.1thinkphp
}
}
} else {
$name = strtoupper(str_replace('.', '_', $env)); //将.改为下划线,然后全部转大写
$this->data[$name] = $value;
}
}
它在app类中关于关联config的执行部分:
流程:
查看load,set两个函数代码可知,.env的配置内容 : CONFIG_EXT= .PHP(或者其他后缀,一旦指定后缀,只能加载指定后缀的配置文件)
调试代码的方法:
1.不停的打断点调试
2.在调用的函数使用php内置函数debug_backtrace查看改函数的调用情况
最后
以上就是唠叨热狗为你收集整理的thinkphp5.1 config类和env类源码剖析 set方法简要分为4个场景:总结:在APP类执行初始化加载配置时,主要用到了第一和第二个场景看完set方法,再看到get方法的场景:4.正常获取配置get和set方法均已讲解完毕,目光看到load方法:ENV类刨析查看load,set两个函数代码可知,.env的配置内容 : CONFIG_EXT= .PHP(或者其他后缀,一旦指定后缀,只能加载指定后缀的配置文件)调试代码的方法:的全部内容,希望文章能够帮你解决thinkphp5.1 config类和env类源码剖析 set方法简要分为4个场景:总结:在APP类执行初始化加载配置时,主要用到了第一和第二个场景看完set方法,再看到get方法的场景:4.正常获取配置get和set方法均已讲解完毕,目光看到load方法:ENV类刨析查看load,set两个函数代码可知,.env的配置内容 : CONFIG_EXT= .PHP(或者其他后缀,一旦指定后缀,只能加载指定后缀的配置文件)调试代码的方法:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复