PHP中捕获致命错误的可靠方法有四种:一、用register_shutdown_function+error_get_last捕获绝大多数致命错误;二、PHP 7+用catch(Error)捕获TypeError等Error类;三、用set_error_handler将E_RECOVERABLE_ERROR转为异常;四、调用前动态检测函数/文件存在性等前置防御。

如果您在PHP中执行函数时遭遇脚本突然终止且无任何异常被捕获,则很可能是发生了致命错误(Fatal Error)。这类错误因发生在Zend引擎执行流程之外或导致其崩溃,无法被常规try/catch拦截。以下是多种可靠捕获函数执行中致命错误的方法:
一、使用register_shutdown_function配合error_get_last
这是唯一能稳定捕获绝大多数致命错误的机制,利用PHP脚本终止前最后可执行钩子,在退出前检查是否发生E_ERROR、E_PARSE等致命类型错误。
1、在项目入口文件最顶部(如index.php第一行)调用register_shutdown_function注册关闭函数。
2、在该函数内部调用error_get_last()获取最后一次错误信息。
立即学习“PHP免费学习笔记(深入)”;
3、判断$error['type']是否属于[E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR]之一。
4、若匹配,则记录日志、写入监控系统或输出预设友好提示页面。
5、确保该函数内仅执行轻量操作,禁止发起数据库写入、HTTP请求或复杂对象序列化,以防资源已释放引发二次崩溃。
二、针对PHP 7+环境启用Error类捕获
PHP 7起将部分原致命错误升级为Error类实例(如TypeError、ParseError、ArithmeticError),这些对象继承自Throwable,可被catch(Error)直接捕获,适用于函数调用链中可预判的类型不匹配或语法问题。
1、在可能触发类型错误的函数调用处包裹try-catch块。
2、使用catch(TypeError $e)或catch(ParseError $e)等具体Error子类进行精确捕获。
3、也可统一使用catch(Throwable $e)覆盖Exception与Error两类。
4、注意:此方式无法捕获E_ERROR(如调用未定义函数)、内存耗尽或语法解析失败(.php文件本身存在语法错误),仅限运行时触发的Error实例。
三、结合set_error_handler处理可恢复致命错误
E_RECOVERABLE_ERROR是一种特殊致命错误,虽标记为“致命”,但PHP允许其被错误处理器接管并转为异常,从而进入try-catch流程,常见于对象成员访问空值、严格类型下返回值协变失败等场景。
1、在脚本初始化阶段调用set_error_handler,传入自定义回调函数。
2、在回调中判断$errno是否等于E_RECOVERABLE_ERROR。
3、若是,手动抛出ErrorException实例,使控制流转入最近的catch块。
4、确保error_reporting配置包含E_RECOVERABLE_ERROR,否则该错误将被静默忽略或直接终止脚本。
四、前置防御:函数调用前动态检测
对高风险函数(如call_user_func、serialize、unserialize、eval、require_once等)执行前做元信息校验,从源头规避致命错误触发条件,属于主动防御策略而非事后捕获。
1、调用函数前使用function_exists()、method_exists()、class_exists()确认符号存在性。
2、对serialize/unserialize操作,先用is_string()和json_validate(或正则粗筛)排除明显非法输入。
3、对eval语句,绝对禁止执行用户可控字符串,必须使用白名单表达式解析器替代。
4、require/require_once前使用file_exists()与is_readable()双检文件状态,并设置error_reporting(0)临时抑制警告。



















