PHP可恢复致命错误无法被try-catch捕获的问题排查
问题解答
为什么try-catch无法捕获这个错误
你遇到的是可恢复致命错误,在PHP7及以后的版本中,这类错误属于Error类的实例,而非普通的Exception。你写的catch(Exception $err)只能捕获业务层面的异常,无法处理系统级的Error错误。如果要捕获这类错误,需要把捕获目标改成Error或者更顶层的Throwable接口:
catch(Throwable $err) { $_SESSION['errors'] .= $err->getMessage(); }
为什么PHP7.3出现问题,PHP5.6不存在
核心问题出在$objects的初始化上——你将它设为了空字符串"",后续却把它当作数组来使用。PHP5.6和7.3对这种“字符串当作数组赋值”的行为处理逻辑不同:
- 在PHP5.6中,当对字符串执行数组下标赋值操作时,如果赋值的是非字符类型(比如对象),PHP会自动把字符串转换为数组,直接完成赋值,不会触发对象转字符串的操作,因此不会报错。
- 在PHP7及以后(包括7.3),PHP对类型的处理更严格:给字符串下标赋值非字符内容时,会强制尝试把赋值内容转换为字符串。而你的
Extra类没有定义__toString()方法,无法将对象转换为字符串,因此抛出了这个致命错误。
修复方案
最直接且符合逻辑的修复是把$objects的初始值从空字符串改为空数组:
$objects = []; $i = 0;
毕竟从代码逻辑来看,$objects就是用来存储对象数组的,一开始就设为数组才符合预期,也不会触发后续的类型转换错误。当然也可以给Extra类添加__toString()方法,但前者才是从根源上解决问题的方式。
内容的提问来源于stack exchange,提问作者Christopher Childs
相关产品推荐
相关产品推荐

