Discuz错误处理不可自定义,应通过Nginx的error_page在Web服务器层统一拦截5xx/4xx错误;强行修改set_error_handler会破坏其内置兜底逻辑,导致白屏或敏感信息泄露。

Discuz 不提供应用层的自定义错误处理入口,强行修改 PHP 错误处理器反而会破坏其异常捕获逻辑,正确做法是绕过它、在 Web 服务器层统一拦截。
Discuz 本身不支持 set_error_handler 替换
Discuz 的错误流程是:PHP 原生错误 → 被 set_error_handler 拦截(Discuz 自带)→ 转为 error_log 或触发 showmessage()。你若在 config/config_global.php 或插件中再次调用 set_error_handler,会导致 Discuz 自身的错误兜底失效,部分致命错误(如模板解析失败、缓存写入失败)直接暴露堆栈或白屏。
常见误操作现象:
- 后台开启“调试模式”后,
showmessage()输出完整$_G数组,含数据库密码、绝对路径 - 自定义 handler 中调用
trigger_error(),引发递归调用,Nginx 返回 500 或超时 - 未检查
error_reporting()当前掩码,结果只捕获了E_NOTICE,漏掉关键E_WARNING(如mysql_connect()失败)
Nginx 层 error_page 是唯一可靠兜底方式
Discuz 的 PHP 错误处理不可信,必须在反向代理层强制截断。Nginx 的 error_page 指令不依赖 PHP 执行,只要 HTTP 状态码返回 4xx/5xx 就生效,包括 PHP 崩溃、超时、FastCGI 错误等所有场景。
实操建议:
- 在站点
server块中添加:error_page 404 /404.html; error_page 500 502 503 504 /50x.html;
- 确保
/404.html和/50x.html放在 Nginxroot指向的静态目录下,且文件权限为644,内容纯 HTML(禁止<!--#include-->、<?php、内联 JS) - 禁用 Discuz 的“友好错误提示”:后台 → 【站长】→ 【系统设置】→ 【站点功能】→ 关闭“显示 PHP 错误信息”
- 验证是否生效:手动访问一个不存在的 URL(如
/xxx.php),确认响应头中Status: 404且页面内容是你写的404.html,而非 Discuz 的forum.php?mod=attachment报错页
Discuz 模板层隐藏敏感变量输出
即使错误被 Nginx 拦截,Discuz 模板里仍可能因逻辑错误泄露路径。例如 template/default/common/header.htm 中误写 {eval echo $_SERVER['DOCUMENT_ROOT'];},或调试代码残留 <!-- {echo $sql} -->。
安全加固要点:
- 搜索整个
template/目录,删除所有{eval、{php、


















