使用 ThinkPHP3.2.3 遇到一個奇怪的問題,正式環境上報錯,提示php
「頁面錯誤!請稍後再試~」html
爲了查看到底出啥錯誤,哪裏出錯,因而在入口文件中加了一段代碼,開啓調試:緩存
defined('APP_DEBUG') or define('APP_DEBUG', true);
再運行程序,頁面又正常顯示,這就奇怪了!服務器
翻了下 ThinkPHP 框架的源代碼,看了下其具體實現,獲得以下幾點認識:框架
先找到默認配置文件 ./ThinkPHP/Conf/convention.php,把 SHOW_ERROR_MSG 選項設置爲 true,再運行一下頁面,顯示函數
模板不存在:/home/jianbao/52php.com/Echo/View/Index2/chargelogintype.htmlthis
好吧,至少讓我看到了問題的根本!url
奇怪的是,頁面的 ACTION 是 chargeLoginType,咋就所有轉成小寫的呢?若是轉成小寫,視圖文件確定是找不到了哦,由於 Linux 服務器是區分文件名大小寫的。spa
找到視圖功能的文件 ./ThinkPHP/Library/Think/View.class.php,裏面有段計算 視圖文件路徑的代碼:debug
$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; 時,就會報錯,提示找不到視圖文件
當爲調試模式,系統會加載配置文件 ./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 不會被系統篡改成小寫,保持原樣。
在計算 視圖文件時,文件名正確,文件也存在,因此不報錯!
(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']));