php如何设置自定义错误页面_php设置自定义错误页面方法【技巧】

14次阅读

php 如何设置自定义错误页面_php 设置自定义错误页面方法【技巧】

PHP 里 http_response_code()header() 哪个该先调用

必须先调用 http_response_code()(或 header('HTTP/1.1 404 Not Found')),再调用 header('Location: /404.php')。否则重定向后状态码会变成 302,搜索引擎和 API 客户端收不到你想要的 404、500 等语义。

常见错误现象:页面跳转了,但浏览器开发者工具 Network 面板里响应状态码是 302,不是 404;curl -I 看到的是 HTTP/1.1 302 Found

  • 如果只是想显示错误页而不跳转,直接 http_response_code(404) + include '404.php' 就够了
  • 如果用了 header('Location: ……'),记得它默认发 302,要显式覆盖:http_response_code(404); header('Location: /404.php'); —— 但注意:这其实不标准,客户端收到 404 状态却跳转,语义矛盾
  • 更合理的方式是:用 302 跳转时,保持状态码为 302;真要返回 404,就别跳转,直接输出内容

Apache 下用 .htaccess 设置 ErrorDocument 的坑

PHP 层面的错误处理控制不了服务器级错误(比如 404 文件不存在、500 PHP 解析失败),这类必须靠 Web 服务器配置。Apache 的 ErrorDocument 是最常用方式,但路径容易写错。

使用场景:用户访问 /nonexistent.php,Apache 直接 404,根本没进 PHP;或者 PHP 崩溃导致 500,set_error_handler 也捕获不到。

立即学习 PHP 免费学习笔记(深入)”;

  • ErrorDocument 404 /errors/404.php:路径是相对于网站根目录(DocumentRoot),不是当前脚本位置
  • 如果站点跑在子目录(如 http://site.com/app/),/errors/404.php 仍要从根开始写,不能写成 /app/errors/404.php
  • 确保 404.php 本身能被公开访问(没被 Deny from all 挡住),且里面手动调用 http_response_code(404),否则默认返回 200
  • Nginx 没有 ErrorDocument,对应的是 error_page 404 /404.html;,语法和路径逻辑不同,别套用

PHP 内部错误(Parse Error、Fatal Error)为什么 set_error_handler 捕获不到

set_error_handler 只捕获 E_WARNING、E_NOTICE 这类“可恢复”错误,对解析失败、致命错误、未捕获异常完全无效。它们发生得太早,PHP 连运行时环境都没完全起来。

真正能兜底的只有两个机制:register_shutdown_functionset_exception_handler,但各自有局限。

  • set_exception_handler 只管未被捕获的 ExceptionError(PHP 7+),不管 ParseError(文件语法错)
  • register_shutdown_function 总会执行,可用 error_get_last() 判断是否发生了致命错误,但无法阻止白屏或默认错误信息输出
  • 关键操作:在 shutdown 函数里检查 error_get_last() 类型是否为 E_PARSEE_ERROR,然后 http_response_code(500) + readfile('500.php') 输出自定义页
  • 注意:此时 PHP 输出缓冲可能已关闭,echo 失效,必须用 readfile 或打开缓冲(ob_start() 得在出错前就开好)

为什么本地开发能显示自定义页,上线后又变默认 Apache 错误页

大概率是生产环境开了 display_errors = Onlog_errors = Off,同时没关掉 Apache 的 AllowOverride None,导致 .htaccess 里的 ErrorDocument 不生效。

性能与兼容性影响:Apache 每次请求都要检查目录下有没有 .htaccess,线上关掉它能提速;但关掉后你就只能去主配置改 ErrorDocument,没法按虚拟主机或目录单独设。

  • 先确认 phpinfo()display_errorsOfflog_errorsOn —— 否则错误会直接打到页面上,盖掉你的自定义页
  • 检查 Apache 配置中对应目录的 AllowOverride 是否包含 FileInfoErrorDocument 所需)
  • curl -I https://yoursite.com/nonexistent 看响应头,确认是否返回了你设的 Location 或状态码,而不是 Apache 默认文本
  • CDN 或反向代理(如 Nginx 做前端)可能吞掉原始状态码,把 404 转成 200 返回给用户,这时得查中间层配置

最常被忽略的一点:自定义错误页本身出错(比如 404.php 里写了 $undefined_var->method()),会导致二次 500,最终 fallback 到服务器默认页 —— 所以错误页代码越简单越好,别引入复杂逻辑或外部依赖。

text=ZqhQzanResources