修複 ThinkPHP3.2.3 拋出異常模組的一個BUG

來源:互聯網
上載者:User

標籤:action   系統   編譯   stat   html   提示   視圖   back   上下   

使用 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‘]));

修複 ThinkPHP3.2.3 拋出異常模組的一個BUG

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.