1.配置类文件
Config.php详解 , tp5的所有配置文件都是基于这个类文件(一定有命名空间)实现的 , 所以学习这个文件十分有必要 , 位置 : \thinkphp\library\think\Config.php
<?php
namespace think;
class Config
{
// 配置参数
private static $config = []; // 这是一个静态属性,仅限于 类内的静态方法访问 self::静态成员
// 参数作用域
private static $range = '_sys_';
// 设定配置参数的作用域
public static function range($range) // 类名::静态成员 , Config::range()
{
self::$range = $range;
if (!isset(self::$config[$range])) {
self::$config[$range] = [];
}
}
/**
* 解析配置文件或内容
* @param string $config 配置文件路径或内容
* @param string $type 配置解析类型
* @param string $name 配置名(如设置即表示二级配置)
* @param string $range 作用域
* @return mixed
*/
public static function parse($config, $type = '', $name = '', $range = '')
{
$range = $range ?: self::$range;
if (empty($type)) {
$type = pathinfo($config, PATHINFO_EXTENSION);
}
$class = false !== strpos($type, '\\') ? $type : '\\think\\config\\driver\\' . ucwords($type);
return self::set((new $class())->parse($config), $name, $range);
}
/**
* 加载配置文件(PHP格式)
* @param string $file 配置文件名
* @param string $name 配置名(如设置即表示二级配置)
* @param string $range 作用域
* @return mixed
*/
public static function load($file, $name = '', $range = '')
{
$range = $range ?: self::$range;
if (!isset(self::$config[$range])) {
self::$config[$range] = [];
}
if (is_file($file)) {
$name = strtolower($name);
$type = pathinfo($file, PATHINFO_EXTENSION);
if ('php' == $type) {
return self::set(include $file, $name, $range);
} elseif ('yaml' == $type && function_exists('yaml_parse_file')) {
return self::set(yaml_parse_file($file), $name, $range);
} else {
return self::parse($file, $type, $name, $range);
}
} else {
return self::$config[$range];
}
}
/**
* 检测配置是否存在
* @param string $name 配置参数名(支持二级配置 .号分割)
* @param string $range 作用域
* @return bool
*/
public static function has($name, $range = '')
{
$range = $range ?: self::$range;
if (!strpos($name, '.')) {
return isset(self::$config[$range][strtolower($name)]);
} else {
// 二维数组设置和获取支持
$name = explode('.', $name);
return isset(self::$config[$range][strtolower($name[0])][$name[1]]);
}
}
/**
* 获取配置参数 为空则获取所有配置
* @param string $name 配置参数名(支持二级配置 .号分割)
* @param string $range 作用域
* @return mixed
*/
public static function get($name = null, $range = '') // 获取配置参数的方法 , 用的最多了
{
$range = $range ?: self::$range;
// 无参数时获取所有
if (empty($name) && isset(self::$config[$range])) {
return self::$config[$range];
}
if (!strpos($name, '.')) {
$name = strtolower($name);
return isset(self::$config[$range][$name]) ? self::$config[$range][$name] : null;
} else {
// 二维数组设置和获取支持
$name = explode('.', $name);
$name[0] = strtolower($name[0]);
return isset(self::$config[$range][$name[0]][$name[1]]) ? self::$config[$range][$name[0]][$name[1]] : null;
}
}
/**
* 设置配置参数 name为数组则为批量设置
* @param string|array $name 配置参数名(支持二级配置 .号分割)
* @param mixed $value 配置值
* @param string $range 作用域
* @return mixed
*/
public static function set($name, $value = null, $range = '')
{
$range = $range ?: self::$range;
if (!isset(self::$config[$range])) {
self::$config[$range] = [];
}
if (is_string($name)) {
if (!strpos($name, '.')) {
self::$config[$range][strtolower($name)] = $value;
} else {
// 二维数组设置和获取支持
$name = explode('.', $name);
self::$config[$range][strtolower($name[0])][$name[1]] = $value;
}
return;
} elseif (is_array($name)) {
// 批量设置
if (!empty($value)) {
self::$config[$range][$value] = isset(self::$config[$range][$value]) ?
array_merge(self::$config[$range][$value], $name) :
self::$config[$range][$value] = $name;
return self::$config[$range][$value];
} else {
return self::$config[$range] = array_merge(self::$config[$range], array_change_key_case($name));
}
} else {
// 为空直接返回 已有配置
return self::$config[$range];
}
}
/**
* 重置配置参数
*/
public static function reset($range = '')
{
$range = $range ?: self::$range;
if (true === $range) {
self::$config = [];
} else {
self::$config[$range] = [];
}
}
}
2.配置目录
2.1默认配置目录
应用的默认配置文件就是application下的config.php , 如果你没有做任何修改的话 , 那么他是和惯例配置文件一样的惯例配置文件的位置 , 一般不建议直接修改这个文件
模块也可以有自己的配置文件 , 一般存放在模块目录下 , 叫config.php
那么怎么查看框架的默认配置文件的内容呢? 使用默认模块下的默认控制器进行访问
public function my_get()
{
dump(\think\Config::get()); // \think\Config::get()
}
tp5.com/index.php/index/index/my_get
2.2自定义配置目录
如果用户想要自定义应用配置目录
的话 , 首先是修改入口文件 , 添加一个系统常量
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
define('CONF_PATH', __DIR__ . '/../config/');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
然后在网站根目录下新建一个config目录 , 然后在里面新建一个config.php , 内容就是返回一个数组
我的感觉就是先加载默认配置 , 然后在加载自定义配置 , 以后者为准
<?php
return [
'site_name' => 'php中文网',
'app_trace' => true,
];
当前这个配置文件对应的是应用的配置文件 , 我们还可以给模块定义配置文件 , 就是在config目录下新建一个和模块名称相同的文件夹 , 然后在里面新建一个config.php , 这样这个配置文件就和模块绑定在一起了
<?php
return [
'my_name' => '朱老师'
];
2.3扩展配置目录
也是在config目录下创建一个新的文件夹 , 叫 extra
, 然后在里面创建一个文件名 , 这个文件名比较特殊 , 就是我们我们想创建的配置项的名称 , 比如我们的配置项叫做my_base , 那么文件名就叫做my_base.php
<?php
return [
'my_name' => '皮特',
'my_age' => 19,
'my_friend' => 'tom'
];
访问 : tp5.com/index.php/index/index/my_get
模块也可以设置自己的扩展配置项 , 就在config\index\extra\my_base.php
ThinkPHP5配置目录主要分为三类 默认配置目录 , 自定义配置目录 和 扩展配置目录,
无论你采用哪一种配置目录,最终都会与应用配置文件合并后输出
3.配置文件的格式
不同的配置文件要在入口文件中新建不同的自定义常量 , 如果是自定义配置文件 , 也需要在入口文件中新建自定义常量
3.1默认格式
配置文件也可以返回一个二级数组
<?php
return [
'my_info' =>[
'site_name' => 'php中文网',
'app_trace' => true,
],
];
3.2ini名值对
入口文件
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
define('CONF_PATH', __DIR__ . '/../config/');
define('CONF_EXT', '.ini'); // 这个
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
然后在config目录下新建一个文件 , 叫config.ini , 然后内容
my_name = peter ;我的名字my_salary = 40000 ;我的薪资 , ;后面是注释
3.3xml格式
入口文件
// 定义应用目录define('APP_PATH', __DIR__ . '/../application/');define('CONF_PATH', __DIR__ . '/../config/');define('CONF_EXT', '.xml'); // 这个// 加载框架引导文件require __DIR__ . '/../thinkphp/start.php';
配置文件 config.xml , 在config目录下
<abc><my_info>< my_home>安徽省合肥市</ my_home><my_job>PHP中文网讲师</my_job></my_info></abc>
3.4json格式
入口文件
// 定义应用目录define('APP_PATH', __DIR__ . '/../application/');define('CONF_PATH', __DIR__ . '/../config/');define('CONF_EXT', '.json'); // 这个// 加载框架引导文件require __DIR__ . '/../thinkphp/start.php';
配置文件 config.json , 在config目录下
{ "base":{ "my_name":"朱老师", "my_age":18, },}
介绍的四种配置文件的格式,实际工作中用得最多的是数组,其它格式,做为了解即可。无论采用哪种格式的配置文件,
最终都是以Aray数组键值对的方式返回。
4.场景配置
不同场景使用不同配置 , 比如在家和公司
必要性
在不同的环境下,使用不同的配置项。例如在家中和在公司中,使用的数据库有可能是不一样的,那么就可以为这二个不同的环境创建不同的数据库连接配置
实现步骤
修改应用或模块配置文件中的 : app_status , 将值设置为 : 场景名称, 如:home在与该配置文件同级的目录下, 创建与场景名称同名的配置文件 , 如 home.php再次执行, 将会自动根据场景配置文件( home.php), 更新当前应用的配置文件。
home.php
<?phpreturn [ // 数据库类型 'type' => 'mysql', // 服务器地址 'hostname' => '127.0.0.1', // 数据库名 'database' => 'home', // 用户名 'username' => 'root_home', // 密码 'password' => 'root_home', // 端口 'hostport' => '3306', // 连接dsn 'dsn' => '', // 数据库连接参数 'params' => [], // 数据库编码默认采用utf8 'charset' => 'utf8',];
模块的场景修改也是一样 , 在模块的配置文件中修改app_status
配置项 , 在同级目录下新建那个配置项值的文件
场景配置,可以看到文件级的动态配置,它为框架的使用者,提供了一种在特殊环境下,简便的解决方案
5.模块配置
模块的配置文件优先级高于应用的配置文件 , 自定义配置目录优先级高于默认应用配置目录
如果要修改模块的场景配置 , 要在配置文件中修改 app_status
的值 , 然后在同级目录下创建一个和值相同的文件
<?phpreturn [ 'my_name' => '朱老师', 'app_status'=> 'office',];
为降低应用的复杂度,提高安全性,绝大多数情况下,模块配置用得并不多,但如果你有个性化需求时,使用模块设置会
方便许多~
6.加载其他位置的配置文件
因为有的开发者就是不喜欢把配置文件放在application下面 , 或者config下面 , 就是玩 , 放在一个奇怪的地方
6.1php文件
举例 : 在config下新建一个newconf目录 , 然后在下面新建一个config.php , 然后加载他
加载方法 , 在控制器下 , Index.php
public function my_get() { \think\Config::load(APP_PATH.'../config/newconf/config.php'); }
config.php
<?phpreturn [ 'wellcome' => '你好啊,欢迎'];
访问
6.2其他格式
举例 : 在上面newconfig的目录下新建一个conf.ini
控制器 Index.php
public function my_get() { \think\Config::parse(APP_PATH.'../config/newconf/conf.ini'); // 换方法了 }
conf.ini
name = pppp ;我的名字
访问
注意: 读取其它位置的配置文件, 都是动态加载, 需要在控制器中的方法中执行加载。
加载任意位置,非php格式的配置文件,不仅提高了灵活性,还有其它应用提供了一个配置接口,请多多练习
7.读取配置项
7.1类方法
类方法: Config:get(配置参数), 参数为空则是获取全部配置项 , 也可以指定参数获取某一项
使用Config类 , 需要用命名空间访问
public function my_get() { dump( \think\Config::get()); }
7.2助手函数
使用助手函数:config(配置参数), 参数说明与 Config::get()完全一样;
public function my_get() { dump(config('app_debug')); }
补充 : 读取二级配置项,参数与值之间用.(点进行连接)。
public function my_get() { dump( \think\Config::get('trace.type')); // 访问trace配置项下的type配置项的值 dump(config('trace.type')); }
7.3判断某配置项是否存在
public function my_get() { dump( \think\Config::has('123')); // 访问trace配置项下的type配置项的值 dump(config('?123')); }
小案例
public function my_get() { $conf = 'app_debuvfg'; $isExist = \think\Config::has($conf); if($isExist){ dump(\think\Config::get($conf)); }else{ return $conf.'配置项不存在'; }; }
上面的代码还可以简化 , 就是每次使用Config类都要加上\think\ , 比较冗余 , 可以在开头引用这个命名空间
use \think\Config; public function my_get() { $conf = 'app_debuvfg'; $isExist = \think\Config::has($conf); if($isExist){ dump(\think\Config::get($conf)); }else{ return $conf.'配置项不存在'; }; }
个人建议使用类方法 , 助手函数隐藏了细节 , 代码的可读性不够好
配置项的读取,是我们日常开发中,最常用的项操作了,也非常简单,课后做上几个相关的练习,下节课学习它的姊妹操作 : 动态设置。
8.正确配置配置项
8.1类方法
Index.php
public function my_pei() { // 逐个配置 Config::set('site_domain','www.123.com'); // 批量配置 $conf = [ 'site_admin' => 'admin', 'site_tools' => 'php工具箱', ]; Config::set($conf); // 二级配置 $conf1 = [ 'name' => 'gg', 'age' => 20, ]; Config::set('info',$conf1); // 获取配置 dump(Config::get()); }
访问
8.2助手函数
public function my_pei() { // 逐个配置 config('site_domain','www.123.com'); // 批量配置 $conf = [ 'site_admin' => 'admin', 'site_tools' => 'php工具箱', ]; config($conf); // 二级配置 $conf1 = [ 'name' => 'gg', 'age' => 20, ]; config('info',$conf1); // 获取配置 dump(config()); }
在控制器的方法中,动态设置配置项,可以临时改变某个配置项,优先级也是最高的
,关于配置项的优先级,后面有专门的课程讨论
9.独立配置(扩展配置)
9.1自定义
用户自定义的独立配置文件必须放在应用或模块下面的 extra 目录下面 , 放在这个目录下的php文件会自动加载
举例 :
extra\database.php
<?phpreturn [ 'username' => 'nbbbbbbb'];
访问
9.2默认独立配置文件
默认独立配置文件 database.php数据库, validate.php验证规则既可以放在 extra下面, 也可放在与应用或模块同级的目录下面。如果放在etra目录下面,优先级大于放在应用或模块的同级目录下面;
虽然默认应用下的config.php , 没有数据库的配置项 , 但是获取的时候竟然有 , 是因为把config.php同级目录下的database.php自动加载到config.php中了 , 作为一个二级数组
9.3php文文件
文件名就是配置项名称,文件返回一个数组
独立配置全部是二级配置
将应用或模块中的部分可归类的配置项独立出来,单独创建配置文件来加载,可以使我们的主配置文件加载更快,执行效率更
10.配置文件加载优先级
优先级顺序
动态配置 > 模块配置 > 应用配置 > 惯例配置(就是在控制器中动态设置)
如果在应用配置中有独立和场景
场景配置>独立配置>应用配置
如果在模块配置中有独立和场景
场景配置>独立配置>应用配置
框架配置分级管理,可以最大限度的满足用户对应用运行环境的个性化需求,配置优先级的概念非常重要,请同学们课后多做练习
11.配置项的作用域
作用域相当于二级配置的名称
配置项的作用域,类似于类或函数的命名空间,就是配置项对用户的可见性,随着应用规模的扩大,配置作用域的效果就越明显