Discuz! 6.0 升級後,特定插件(銀行模板)在 PHP 5.2.0+ 環境出現白屏,無錯誤日誌。同插件在 5.1 / 5.0 正常。
templates.func.php 正則處理異常,用 5.5 代碼覆蓋暫時正常,但未定位根因。pcre.backtrack_limit、pcre.recursion_limit 預設值(100000、100000),大模板正則回溯超限導致 preg_replace 靜默失敗返回 null,致使輸出為空白屏。pcre.backtrack_limit = 1000000
pcre.recursion_limit = 1000000
; 或設為 -1 代表無限制(慎用,可能導致 CPU 耗盡)
.*、.+ 貪婪匹配,改用具體字元類別 [^>]*。preg_replace_callback 分段處理。PCRE 採用回溯式 NFA 引擎,嵌套量詞(如 (.*)*)在長字串上呈指數級回溯。PHP 5.2 引入限制是為了防禦 ReDoS,但預設值對大型模板過於保守。
error_reporting(E_ALL); ini_set('display_errors', 1);,白屏才能看到 PREG_BACKTRACK_LIMIT_ERROR 警告。microtime() 測量 preg_replace 耗時,超 100ms 即優化。「白屏無報錯」多為致命錯誤被吞噬。PHP 5.2 pcre.backtrack_limit 是隱形殺手,調大限制治標,優化正則、升級 PHP 才是治本。