修复 ThinkPHP3.2.3 抛出异常模块的一个BUG

使用 ThinkPHP3.2.3 遇到一个奇怪的问题,正式环境上报错,提示

“页面错误!请稍后再试~”

为了查看到底出啥错误,哪里出错,于是在入口文件中加了一段代码,开启调试:

defined(‘APP_DEBUG‘) or define(‘APP_DEBUG‘, true); 

再运行程序,页面又正常显示,这就奇怪了!

翻了下 ThinkPHP 框架的源代码,看了下其具体实现,得到如下几点认识:

1、当 define(‘APP_DEBUG‘, false); 时,发生错误显示效果如下图所示,只展示一句很笼统的提示语:

2、当 define(‘APP_DEBUG‘, true); 时,发生错误显示效果如下图所示,会显示出什么错?哪里出错?具体的上下文(TRACE)是什么?

3、疑问(1):当我未开启调试 define(‘APP_DEBUG‘, false); 时,如何显示简要的出错信息,而不是默认的笼统的信息“页面错误!请稍后再试~”呢?

先找到默认配置文件 ./ThinkPHP/Conf/convention.php,把 SHOW_ERROR_MSG 选项设置为 true,再运行一下页面,显示

模板不存在:/home/wwwroot/52php.com/jck/Economic/View/Index2/chargelogintype.html

好吧,至少让我看到了问题的根本!

奇怪的是,页面的 ACTION 是 chargeLoginType,咋就全部转成小写的呢?如果转成小写,视图文件肯定是找不到了哦,因为 Linux 服务器是区分文件名大小写的。

找到视图功能的文件 ./ThinkPHP/Library/Think/View.class.php,里面有段计算 视图文件路径的代码:

$templateFile = $this->parseTemplate($templateFile);

当没有传 视图文件名时,取跟 ACTION_NAME 同名的视图文件。

再找到路由分发功能的文件 ./ThinkPHP/Library/Think/Dispatcher.class.php,里面有段计算 ACTION_NAME 的代码:

$urlCase =  C(‘URL_CASE_INSENSITIVE‘);
define(‘ACTION_NAME‘, defined(‘BIND_ACTION‘) ? BIND_ACTION : self::getAction($varAction, $urlCase));

也就是说,当你配置了 URL_CASE_INSENSITIVE = true; // 默认false 表示URL区分大小写 true则表示不区分大小写,ACTION_NANE 会被强制转为小写。

总结:

当未开启调试 define(‘APP_DEBUG‘, false); 且 URL_CASE_INSENSITIVE = false; 时,就会报错,提示找不到视图文件

4、疑问(2):当我开启调试 define(‘APP_DEBUG‘, true); 时,为何页面又正常了?

当为调试模式,系统会加载配置文件 ./ThinkPHP/Conf/debug.php,内容如下:

// 调试模式下面默认设置 可以在应用配置目录下重新定义 debug.php 覆盖
return  array(
    ‘LOG_RECORD‘            =>  true,  // 进行日志记录
    ‘LOG_EXCEPTION_RECORD‘  =>  true,    // 是否记录异常信息日志
    ‘LOG_LEVEL‘             =>  ‘EMERG,ALERT,CRIT,ERR,WARN,NOTIC,INFO,DEBUG,SQL‘,  // 允许记录的日志级别
    ‘DB_FIELDS_CACHE‘       =>  false, // 字段缓存信息
    ‘DB_DEBUG‘				=>  true, // 开启调试模式 记录SQL日志
    ‘TMPL_CACHE_ON‘         =>  false,        // 是否开启模板编译缓存,设为false则每次都会重新编译
    ‘TMPL_STRIP_SPACE‘      =>  false,       // 是否去除模板文件里面的html空格与换行
    ‘SHOW_ERROR_MSG‘        =>  true,    // 显示错误信息
    ‘URL_CASE_INSENSITIVE‘  =>  false,  // URL区分大小写
);

看到没,里面有个 URL_CASE_INSENSITIVE = false,表示 URL区分大小写,即 ACTION_NAME 不会被系统篡改为小写,保持原样。

在计算 视图文件时,文件名正确,文件也存在,所以不报错!

5、最后的建议:

(1) 正式环境 define(‘APP_DEBUG‘, false); 不然的话,系统会记录大量的日志信息,好多不是自己想要记录的。

小技巧:

在 入口文件中,增加是否开启 调试模式的开关变量,参考代码如下:

if ((CUR_ENV != ‘production‘) || (isset($_GET[‘debug‘]) && ($_GET[‘debug‘] == ‘52php‘))) {
	define(‘APP_DEBUG‘, TRUE);
}

(2) 找到配置文件 ./ThinkPHP/Conf/convention.php,配置如下:

‘URL_CASE_INSENSITIVE‘  =>  false, // 默认false 表示URL区分大小写,true则表示不区分大小写
‘SHOW_ERROR_MSG‘ => true, // 显示错误信息

(3) 尽管在正式环境 没有开启 DEBUG 模式,但是因为开启了 SHOW_ERROR_MSG = true,所有当有错误时,还是会显示(简要的)错误信息,信息当中可能会暴露 服务器绝对路径等敏感信息,

模板不存在:/home/wwwroot/52php.com/jck/Economic/View/Index2/chargelogintype.html

所以需要做些过滤操作,把绝对路径去掉,展示为相对路径。

找到文件 ./ThinkPHP/Library/Think/Think.class.php,找到函数 static public function halt($error) {...},在以下代码

// 包含异常页面模板
$exceptionFile = C ( ‘TMPL_EXCEPTION_FILE‘, null, THINK_PATH . ‘Tpl/think_exception.tpl‘ );

之前,增加代码:

// 过滤掉 服务绝对路径信息
isset($e[‘message‘]) && ($e[‘message‘] = str_replace(ROOT_PATH, ‘‘, $e[‘message‘]));
时间: 2024-10-05 04:19:37

修复 ThinkPHP3.2.3 抛出异常模块的一个BUG的相关文章

声明了一个模块和一个控制器AngularJS的处理过程

例如下面这段代码.这是一个简单的应用,声明了一个模块和一个控制器: angular.module('myApp', []) .factory('greeter', function() { return { greet: function(msg) {alert(msg);} } }) .controller('MyController',function($scope, greeter) { $scope.sayHello = function() { greeter.greet("Hello

Node.js -- Router模块中有一个param方法

这段时间一直有在看Express框架的API,最近刚看到Router,以下是我认为需要注意的地方: Router模块中有一个param方法,刚开始看得有点模糊,官网大概是这么描述的: 1 Map logic to route parameters. 大概意思就是路由参数的映射逻辑 这个可能一时半会也不明白其作用,尤其是不知道get和param的执行顺序 再看看源码里面的介绍: 1 2 3 Map the given param placeholder `name`(s) to the given

Python 官方代码threading模块的一个死锁的bug

Python的threading模块有一个比较严重的bug:那就是可能会让线程的等待提前结束或者延迟,具体的原因是因为线程的wait操作判断超时时依赖于实时时间,即通过time.time()获取到的时候,为了显示这个问题,请看下面的例子: from threading import Thread from threading import Event import time e = Event() stop = False class MyThread(Thread): def __init__

(知识分享)软硬件调试九法:第九条规则 如果你不修复一个bug,它将永远 存在

1.查证问题确已被修复 如果遵循了“制造失败”这条规则,就知道如何验证你确实修复了问题.无论问题和修复看起来多么明显,你都无法保证修复是有效的,直到做了测试并验证. 2.查证确实你的修复措施解决了问题 如果你取消这个修复,系统再次出现失败,再应用这个修复,问题消失,才能够证明你确实修复了问题.这样做的原因是,在调试期间,往往会改变一些不属于修复的地方,有时这些改变会隐藏问题,如果没有意识到这一点,发现测试起作用了,就高高兴兴的回家了,因为你做的修复和问题消失毫无关系,因此修复方案到达客户后,可能

Turtle模块,一个超精简但功能齐全的绘图包

先上官方链接https://docs.python.org/3.3/library/turtle.html 再上一个GitHub上别人做的一个小程序,画小猪佩琦的,里面用到了大量常用的turtle接口.github链接https://github.com/Monster12138/- Turtle模块,一个超精简但功能齐全的绘图包 原文地址:https://www.cnblogs.com/cia2018/p/10264829.html

(四)一个bug的生命周期

Bug的属性 Bug重现环境 这个应该是我们重现BUG的一个前提,如果没有这个前提,我们可能会无法重现问题,或者根本就无从下手. ? 操作系统 这个是一般软件运行的一大前提,基本上所以批的软件都依赖于操作系统之上的,对于一个软件来说,要想在某个操作系统上运行,必须要对这个操作系统支持,这就需要有针对性的设计与开发.对于不同的操作系统,其可能存在差异(如:win xp 与win 7)或本质的区别(如 win 7 与 CentOS linux),所以,操作系统环境是重现问题的一个重要前提. ? 浏览

记录一个使用HttpClient过程中的一个bug

最近用HttpClient进行链接请求,开了多线程之后发现经常有线程hang住,查看线程dump java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketI

有人向我反馈了一个bug

//我是一个前端开发者,但我想这个故事对任何开发者都会引起共鸣的 有人向你反馈了一个 bug. “26 楼会议室的灯亮着.它需要被熄灭.”bug 的备注里写道“你应该能在 5 分钟内搞定,只要按一下开关就好了.“ 你去了 26 楼的会议室.灯的确亮着,但房间里没有灯的开关. 所以,你准备安装一个.但设计师说,它会破坏房间的美感.另外,墙壁是混凝土.你需要合适的工具才能安装开关.但是,没有人会批准购买这些工具.如果没有合适的工具,安装开关将需要两天.他们希望你现在就能把灯关上,因为他们害怕 CEO

AIX6.1/11.2.0.3在有关数据库SWAP一个BUG

昨天南京到客户服务数据库的优化调整,其中新上线,经过审查alert.log当日志现在是在过去一段时间内取得,每隔几个小时的时间滞后,班会报似的内容: Thu Aug 21 09:01:26 2014 WARNING: Heavy swapping observed on system in last 5 mins. pct of memory swapped in [8.42%] pct of memory swapped out [2.16%]. Please make sure there