3.2 - 致命 - 未处理
bug描述:在入口文件中配置
简单配置如下
// ThinkPHP 入口文件
if(version_compare(PHP_VERSION,'5.3.0','<')) die('require PHP > 5.3.0 !');
define('APP_PATH','../Application/');
require '../ThinkPHP/ThinkPHP.php';默认调试模式是关闭的Application
├─Common 应用公共模块
│ ├─Common 应用公共函数目录
│ └─Conf 应用公共配置文件目录
│ └─config.php 应用公共配置文件
├─Home 默认生成的Home模块
│ ├─Conf 模块配置文件目录
│ ├─Common 模块函数公共目录
│ ├─Controller 模块控制器目录
│ ├─Model 模块模型目录
│ └─View 模块视图文件目录
├─Runtime 运行时目录
│ ├─Cache 模版缓存目录
│ ├─Data 数据目录
│ ├─Logs 日志目录
│ └─Temp 缓存目录
当我们在应用公共配置文件中配置好后
比如:数据库的相关信息
只能开启调试模式才能或者把配置信息放到模块配置文件中才能生效
原因在:
打开ThinkPHP3.2的入口文件ThinkPHP.php,找到33行
defined('APP_STATUS') or define('APP_STATUS', ''); // 应用状态 加载对应的配置文件

这里拿到的是空字符串
因为APP_STATUS常量在项目入口文件中没有被定义就重先定义,但定义时又是一个空字符串
在看导入文件如图:

目录 ThinkPHP/Library/Think/Think.class.php 打开这个文件
在打开这个文件之前 你得了解ThinkPHP.php入口文件调用的方法

Think\Think::start();
调用了Think.class.php类文件start()的静态方法
找到这个方法 89 行左右
// 读取当前应用状态对应的配置文件
if(APP_STATUS && is_file(COMMON_PATH.'Conf/'.APP_STATUS.'.php'))
C(include COMMON_PATH.'Conf/'.APP_STATUS.'.php'); 这里判断 APP_STATUS 常量 肯定假 不用说所以说这里导入就出错了
解决办法:
1、直接在项目入口文件中添加 define('APP_STATUS', 'config');
2、bug建议:

改为:
defined('APP_STATUS') or define('APP_STATUS', 'config'); // 应用状态 加载对应的配置文件
如果开启了调试模式 而且 又配置了调试模式 debug.php 配置文件
直接找到Think.class.php类文件start()的静态方法的 41行 左右
if(!APP_DEBUG && Storage::has($runtimefile,'runtime')){这里判断APP_DEBUG是否开启 默认是关闭的 在入口文件中么也没开启这里执行了 else 中的代码 找到
if(!APP_DEBUG){
$content .= "\nnamespace { Think\Think::addMap(".var_export(self::$_map,true).");";
$content .= "\nL(".var_export(L(),true).");\nC(".var_export(C(),true).');Think\Hook::import('.var_export(Hook::get(),true).');}';
Storage::put($runtimefile,strip_whitespace('<?php '.$content),'runtime');
}else{
// 调试模式加载系统默认的配置文件
C(include THINK_PATH.'Conf/debug.php');
// 读取应用调试配置文件
if(is_file(COMMON_PATH.'Conf/debug.php'))
C(include COMMON_PATH.'Conf/debug.php');
}
这一段 又进行了判断 其实是画蛇添足 不用想 这里肯定执行的是 else 中的代码 也看的出来 这里就是导入debug.php配置文件
在看到下面的
// 读取当前应用状态对应的配置文件
if(APP_STATUS && is_file(COMMON_PATH.'Conf/'.APP_STATUS.'.php'))
C(include COMMON_PATH.'Conf/'.APP_STATUS.'.php');

如果debug.php中的配置项与config.php重复将替换
说明文档是这样说的
应用配置
应用配置文件也就是调用所有模块之前都会首先加载的公共配置文件(默认位于Application/Common/Conf/config.php)。
如果更改了公共模块的名称的话,公共配置文件的位置也相应改变
调试配置
如果开启调试模式的话,则会自动加载框架的调试配置文件(位于ThinkPHP/Conf/debug.php)和应用调试配置文件(位于Application/Common/Conf/debug.php)
这样一来不就刚好反过来了吗 不是debug.php中的配置项去替换config.php
我们需要修改这里
/*if(!APP_DEBUG){
$content .= "\nnamespace { Think\Think::addMap(".var_export(self::$_map,true).");";
$content .= "\nL(".var_export(L(),true).");\nC(".var_export(C(),true).');Think\Hook::import('.var_export(Hook::get(),true).');}';
Storage::put($runtimefile,strip_whitespace('<?php '.$content),'runtime');
}else{
// 调试模式加载系统默认的配置文件
C(include THINK_PATH.'Conf/debug.php');
// 读取应用调试配置文件
if(is_file(COMMON_PATH.'Conf/debug.php'))
C(include COMMON_PATH.'Conf/debug.php');
}*/
}
// 读取当前应用状态对应的配置文件
if(APP_STATUS && is_file(COMMON_PATH.'Conf/'.APP_STATUS.'.php'))
C(include COMMON_PATH.'Conf/'.APP_STATUS.'.php');
if(APP_DEBUG) {
// 调试模式加载系统默认的配置文件
C(include THINK_PATH.'Conf/debug.php');
// 读取应用调试配置文件
if(is_file(COMMON_PATH.'Conf/debug.php'))
C(include COMMON_PATH.'Conf/debug.php');
}
把前面的注释掉 在后面进行判断
我想有些人觉得奇怪 为什么前面的 整个if语句被注释掉了 开始判断 if(!APP_DEBUG) 为真实不执行吗?
你放心把 这里的代码永远不会执行的
在上一个if判断语句中 就能找到答案 两处一模一样
一旦要执行 if(!APP_DEBUG) 里面的代码 下面else就不会执行了
有点奇怪的就是 这段代码 为什么会这样写 为了添加代码量吗
