修复 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/jianbao/52php.com/Echo/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); 不然的话,会显示详细的TRACE信息,并且会记录大量的日志信息,好多不是想要记录的。
小技巧:
在 入口文件中,增加是否开启 调试模式的开关变量,参考代码如下:
if ((CUR_ENV != 'production') || (isset($_GET['debug']) && ($_GET['debug'] == '52php'))) {
define('APP_DEBUG', TRUE);
}
(2) 找到配置文件 ./ThinkPHP/Conf/convention.php,配置如下:
'LOG_RECORD' => false, // 关闭日志功能
'URL_CASE_INSENSITIVE' => false, // 默认false 表示URL区分大小写,true则表示不区分大小写
'SHOW_ERROR_MSG' => true, // 显示错误信息,
'DB_FIELDS_CACHE' => false, // 关闭数据表字段缓存
'TMPL_CACHE_ON' => false, // 关闭模板缓存
(3) 尽管在正式环境 没有开启 DEBUG 模式,但是因为开启了 SHOW_ERROR_MSG = true,所以当有错误时,还是会显示(简要的)错误信息,信息当中可能会暴露 服务器绝对路径等敏感信息,
模板不存在:/home/jianbao/52php.com/Echo/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']));
修复 ThinkPHP3.2.3 抛出异常模块的一个BUG,关闭字段缓存功能的更多相关文章
- 印象最深的一个bug:sessionStorage缓存在移动端失效
无bug,不程序:作为程序员的我,不是修bug就是在写bug的路上. 移动端sessionStorage缓存失效是我"印象最深的一个bug"之一,为啥呢,因为这个问题导致我加班到很 ...
- 关于nodejs,request模块的一个bug
今天在使用request时发生了一个错误, 对方网站的证书设置的不正确导致本地请求不能返回数据: 解决方案是在配置request时加入一个忽略证书验证得字段: 具体代码如下 request.post( ...
- 利用Node.js的Net模块实现一个命令行多人聊天室
1.net模块基本API 要使用Node.js的net模块实现一个命令行聊天室,就必须先了解NET模块的API使用.NET模块API分为两大类:Server和Socket类.工厂方法. Server类 ...
- Node.js -- Router模块中有一个param方法
这段时间一直有在看Express框架的API,最近刚看到Router,以下是我认为需要注意的地方: Router模块中有一个param方法,刚开始看得有点模糊,官网大概是这么描述的: 1 Map lo ...
- 从修复 testerhome(rubychina)网站的一个 bug 学习 ruby&rails on ruby
前言 testerhome: http://testerhome.com/topics/1480 对于一个差点脱离前沿技术人,想要学习ruby,就意味着要放弃熟悉的操作系统windows,熟悉的ide ...
- 第三百五十节,Python分布式爬虫打造搜索引擎Scrapy精讲—selenium模块是一个python操作浏览器软件的一个模块,可以实现js动态网页请求
第三百五十节,Python分布式爬虫打造搜索引擎Scrapy精讲—selenium模块是一个python操作浏览器软件的一个模块,可以实现js动态网页请求 selenium模块 selenium模块为 ...
- 二十九 Python分布式爬虫打造搜索引擎Scrapy精讲—selenium模块是一个python操作浏览器软件的一个模块,可以实现js动态网页请求
selenium模块 selenium模块为第三方模块需要安装,selenium模块是一个操作各种浏览器对应软件的api接口模块 selenium模块是一个操作各种浏览器对应软件的api接口模块,所以 ...
- 趣图:快下班了,剩一个bug,修复一下再走
趣图:当我给老板展示我修复了那个 bug 时 趣图:当我以为这是最后一个Bug时……
- 利用random模块做一个抢红包功能
我们都知道random模块是一个生成随机数的模块,用它来做抢红包的功能很合适. 抢红包,抢到的金额是随机的,但怎么让每个人抢到的随机金额公平合理呢 比如:我想发一个100元的红包让10个人抢,我可以把 ...
随机推荐
- JavaScript 基础回顾——对象
JavaScript是基于对象的解释性语言,全部数据都是对象.在 JavaScript 中并没有 class 的概念,但是可以通过对象和类的模拟来实现面向对象编程. 1.对象 在JavaScript中 ...
- Jsp 错题分析
ArrayList删除元素通过RemoveAt(int index)来删除指定索引值的元素 运行时异常都是RuntimeException类及其子类异常,如NullPointerException.I ...
- Linux档案与目录管理
Linux档案与目录管理1. 目录与路径1.1 相对路径与绝对路径1.2 目录的相关操作: cd, pwd, mkdir, rmdir cd [相对路径或绝对路径]cd ~ [用户]: 切换家目录cd ...
- python_爬虫一之爬取糗事百科上的段子
目标 抓取糗事百科上的段子 实现每按一次回车显示一个段子 输入想要看的页数,按 'Q' 或者 'q' 退出 实现思路 目标网址:糗事百科 使用requests抓取页面 requests官方教程 使用 ...
- HOLOLENS程序发布,这个界面调用的图片
SplashScreen.scale-200.png 1240 x 600
- 如何正确使用 Composer 安装 Laravel 扩展包
我们经常要往现有的项目中添加扩展包,有时候因为文档的错误引导,如下图来自 这个文档 的: composer update 这个命令在我们现在的逻辑中,可能会对项目造成巨大伤害. 因为 composer ...
- Mac如何找到从AppStore下载的正版Xcode安装包
前言:本文介绍在Mac下如何找到AppStore下载的安装包路径,以及如何提取出来供以后使用,希望对大家有所帮助(前提:想要提取某个安装包,前提是你正在从AppStore安装这个程序.比如你想提取im ...
- codevs 2495 水叮当的舞步
题目链接:水叮当的舞步 我现在开始发题目链接了(主要还是因为懒得整理题面)-- 这道题一开始是看到MashiroSky在写,于是我也开始写这道题了(说白了就是狙击他)-- 这道题看到这么小的范围当然给 ...
- Nginx负载均衡实践之一:基本实现
由于现在的网站架构越来越大,基于互联网的用户也是日渐增长,所以传统的单机版服务器已经渐渐不能适应时代发展的需要.最近在和其他企业接触的过程中,发现对于互联网的经验尤为看重,所谓的互联网经验,其实就是指 ...
- jquery替换所有逗号
代码: var aa= $("input[name=aa]").val().replace(/\,/g,""); 原文:http://blog.csdn.net ...