🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] * * * * * ## 1 全局配置文件 /thinkphp/library/think/Config.php 配置项操作类 /thinkphp/convention.php 全局默认配置项 ## 2 全局配置入口分析 全局配置项目的分析入口在/thinkphp/start.php中, 默认情况下的运行模式是common模式 因此会加载/thinkphp/mode/common.php模式配置文件。 配置项操作类Config的加载是 ~~~ if (isset($mode['namespace'])) { Loader::addNamespace($mode['namespace']); } ~~~ 根据common.php模式配置文件可知 ~~~ 'namespace' => [ 'think' => LIB_PATH . 'think' . DS, 'behavior' => LIB_PATH . 'behavior' . DS, 'traits' => LIB_PATH . 'traits' . DS, APP_NAMESPACE => APP_PATH, ], ~~~ 自动注册命名空间目录到Loader加载器中,加载器的实现见 附:自动加载器 ~~~ if (isset($mode['config'])) { is_array($mode['config']) ? Config::set($mode['config']) : Config::load($mode['config']); } ~~~ 检查模式是否设置了$mode['config'] 检查$mode['config']是否是数组,数组的情况下调用Config::set()添加到全局配置,如果不是数组则默认为文件,使用Config::load()加载相应的配置文件到全局配置。 其中的$mode['config']为THINK_PATH . 'convention' . EXT, 因此会加载/thinkphp/convention.php文件作为配置文件 ## 2 配置控制类Config文件分析 ~~~ private static $config = []; private static $range = '_sys_'; ~~~ 静态变量 $config 全局配置参数存储 静态变量 $range 配置参数作用域 ~~~~ public static function range($range) { self::$range = $range; if (!isset(self::$config[$range])) { self::$config[$range] = []; } } ~~~ range()设置配置参数的作用域 也就是静态变量$range ~~~ public static function parse($config, $type = '', $range = '') { $range = $range ?: self::$range; if (empty($type)) { $type = pathinfo($config, PATHINFO_EXTENSION); } $class = (false === strpos($type, '\\')) ? '\\think\\config\\driver\\' . ucwords($type) : $type; self::set((new $class())->parse($config), '', $range); } ~~~ 调用\think\config\driver\下的配置解析器 框架默认包含两种配置解析器 ini.php和xml.php ~~~ public static function load($file, $name = '', $range = '') { $range = $range ?: self::$range; if (!isset(self::$config[$range])) { self::$config[$range] = []; } APP_DEBUG && Log::record('[ CONFIG ] ' . $file, 'info'); return is_file($file) ? self::set(include $file, $name, $range) : self::$config[$range]; } ~~~ load() 加载配置文件, ~~~ public static function has($name, $range = '') { $range = $range ?: self::$range; $name = strtolower($name); if (!strpos($name, '.')) { return isset(self::$config[$range][$name]); } else { $name = explode('.', $name); return isset(self::$config[$range][$name[0]][$name[1]]); } } ~~~ has()检查某个配置项是否存在 ~~~ public static function get($name = null, $range = '') { $range = $range ?: self::$range; if (empty($name) && isset(self::$config[$range])) { return self::$config[$range]; } $name = strtolower($name); if (!strpos($name, '.')) { if (isset($_ENV[ENV_PREFIX . $name])) { return $_ENV[ENV_PREFIX . $name]; } return isset(self::$config[$range][$name]) ? self::$config[$range][$name] : null; } else { $name = explode('.', $name); if (isset($_ENV[ENV_PREFIX . $name[0] . '_' . $name[1]])) { return $_ENV[ENV_PREFIX . $name[0] . '_' . $name[1]]; } return isset(self::$config[$range][$name[0]][$name[1]]) ? self::$config[$range][$name[0]][$name[1]] : null; } } ~~~ get() 获取某个配置项的值 ~~~ public static function set($name, $value = null, $range = '') { $range = $range ?: self::$range; if (!isset(self::$config[$range])) { self::$config[$range] = []; } if (is_string($name)) { $name = strtolower($name); if (!strpos($name, '.')) { self::$config[$range][$name] = $value; } else { $name = explode('.', $name); self::$config[$range][$name[0]][$name[1]] = $value; } return; } elseif (is_array($name)) { $config = array_change_key_case($name); if (!empty($value)) { self::$config[$range][$value] = isset(self::$config[$range][$value]) ? array_merge(self::$config[$range][$value], $config) : self::$config[$range][$value] = $config; return self::$config[$range][$value]; } else { return self::$config[$range] = array_merge(self::$config[$range], $config); } } else { return self::$config[$range]; } } ~~~ set() 设置某个配置项的值 ~~~ public static function reset($range = '') { $range = $range ?: self::$range;true === $range ? self::$config = [] : self::$config[$range] = []; } ~~~ reset() 清空全局配置信息 ## 3 配置项conventtion.php文件分析 ~~~ return [ // 应用模式状态 'app_status' => '', // 注册的根命名空间 'root_namespace' => [], // 扩展配置文件 'extra_config_list' => ['database', 'route', 'validate', 'auto'], // 扩展函数文件 'extra_file_list' => [THINK_PATH . 'helper' . EXT], // 默认输出类型 'default_return_type' => 'html', // 默认语言 'default_lang' => 'zh-cn', // response是否返回方式 'response_return' => false, // 默认AJAX 数据返回格式,可选JSON XML ... 'default_ajax_return' => 'JSON', // 默认JSONP格式返回的处理方法 'default_jsonp_handler' => 'jsonpReturn', // 默认JSONP处理方法 'var_jsonp_handler' => 'callback', // 默认时区 'default_timezone' => 'PRC', // 是否开启多语言 'lang_switch_on' => false, // 支持的多语言列表 'lang_list' => ['zh-cn'], // 语言变量 'lang_detect_var' => 'lang', // 语言cookie变量 'lang_cookie_var' => 'think_lang', // 默认全局过滤方法 用逗号分隔多个 'default_filter' => '', // 默认模块名 'default_module' => 'index', // 禁止访问模块 'deny_module_list' => [COMMON_MODULE, 'runtime'], // 默认控制器名 'default_controller' => 'Index', // 默认操作名 'default_action' => 'index', // 默认的空控制器名 'empty_controller' => 'Error', // 操作方法后缀 'action_suffix' => '', // PATHINFO变量名 用于兼容模式 'var_pathinfo' => 's', // 兼容PATH_INFO获取 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], // pathinfo分隔符 'pathinfo_depr' => '/', // 获取当前页面地址的系统变量 默认为REQUEST_URI 'url_request_uri' => 'REQUEST_URI', // 基础URL路径 'base_url' => $_SERVER["SCRIPT_NAME"], // URL伪静态后缀 'url_html_suffix' => '.html', // URL普通方式参数 用于自动生成 'url_common_param' => false, //url禁止访问的后缀 'url_deny_suffix' => 'ico|png|gif|jpg', // 是否开启路由 'url_route_on' => true, // 是否强制使用路由 'url_route_must' => false, // URL模块映射 'url_module_map' => [], // 域名部署 'url_domain_deploy' => false, // 域名根,如.thinkphp.cn 'url_domain_root' => '', // 是否自动转换URL中的控制器名 'url_controller_convert' => true, // 是否自动转换URL中的操作名 'url_action_convert' => true, // 默认跳转页面对应的模板文件 'dispatch_success_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', 'dispatch_error_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', // 默认的模板引擎 'template_engine' => 'Think', // 异常页面的模板文件 'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl', // 异常处理忽略的错误类型,支持PHP所有的错误级别常量,多个级别可以用|运算法 // 参考:http://php.net/manual/en/errorfunc.constants.php 'exception_ignore_type' => 0, // 错误显示信息,非调试模式有效 'error_message' => '页面错误!请稍后再试~', // 错误定向页面 'error_page' => '', // 显示错误信息 'show_error_msg' => false, 'log' => [ 'type' => 'File', // 支持 file socket trace sae 'path' => LOG_PATH, ], 'cache' => [ 'type' => 'File', 'path' => CACHE_PATH, 'prefix' => '', 'expire' => 0, ], // 是否使用session 'use_session' => true, 'session' => [ 'id' => '', 'var_session_id' => '', // SESSION_ID的提交变量,解决flash上传跨域 'prefix' => 'think', 'type' => '', 'auto_start' => true, ], 'db_fields_strict' => true, 'database' => [ // 数据库类型 'type' => 'mysql', // 数据库连接DSN配置 'dsn' => '', // 服务器地址 'hostname' => 'localhost', // 数据库名 'database' => '', // 数据库用户名 'username' => 'root', // 数据库密码 'password' => '', // 数据库连接端口 'hostport' => '', // 数据库连接参数 'params' => [], // 数据库编码默认采用utf8 'charset' => 'utf8', // 数据库表前缀 'prefix' => '', // 数据库调试模式 'debug' => false, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) 'deploy' => 0, // 数据库读写是否分离 主从式有效 'rw_separate' => false, // 读写分离后 主服务器数量 'master_num' => 1, // 指定从服务器序号 'slave_no' => '', ], ]; ~~~ 返回一个数组作为全局默认配置 ## 4 总结 经过启动流程的/thinkphp/start.php。 会根据系统的运行模式common.php配置文件, 自动加载配置操作类Class Config, 并加载框架的默认全局配置文件/thinkphp/convention.php. convention.php 包括了全局默认配置项 Config.php 定义了配置项操作和配置参数的存储地方静态变量$config, 包含基本的set() get() has() load() parse() reset()操作 **可以看做普通的类的属性操作扩展实现** convention.php 包含了全局默认配置. ## 5全局变量(base.php),模式配置(common.php),全局配置(convention.php)比较 | 文件 |加载位置与顺序 |定义方式 |定义内容 | | -- | -- | -- | -- | | base.php | start.php中,第一个加载 | define | 配置全局信息 | | common.php |start.php中,第二个加载 | array | 配置运行环境信息 | | convention.php |common.php中,第三个加载 |array |配置框架组织信息 | 全局配置文件涉及框架运行的各个方面,其使用见使用范例的 框架配置