PHP 7.4中debug_backtrace()返回空数组的原因排查
为什么debug_backtrace()在PHP 7.4的try-catch块中返回空数组?
我用PHP 7.4编写的顶级脚本/home/path/a.php包含多个try-catch块,用于捕获用户错误及运行时错误,抛出异常时会记录错误日志,其中包含debug_backtrace()的输出。
代码示例
// some code use some/path/to/objects; $database = new Database(); include "some/file/reference.php"; try { // various things including $_SESSION data if (empty($_SESSION['b']) || empty($_POST['d'])) { if(empty($_SESSION['b'])) { error_log("session appears empty. No b"); } if(empty($_POST['d'])) { error_log("POST appears empty. No d"); } throw new RuntimeException('Incorrect validation/form details given.'); } } catch (RuntimeException | Exception $ex) { error_log("Login Page: ".$_SESSION['message']); error_log("debug: ".print_r(debug_backtrace(),true)); }
错误日志输出
[31-Jul-2023 18:42:17 Europe/London] Some custom feedback message from $_SESSION['message']
[31-Jul-2023 18:42:17 Europe/London] Array
(
)
问题原因与解决方法
1. debug_backtrace()的本质是记录调用栈,而非上下文数据
debug_backtrace()返回的是当前执行点的函数/方法调用栈轨迹,不是当前的变量、SESSION或请求参数。你的代码中,throw和catch都处于顶级全局作用域(没有任何函数、方法调用),此时调用栈是空的,自然返回空数组。
之前其他场景能正常获取内容,是因为那些场景中异常是在函数、方法内部抛出,或者存在多层函数调用,调用栈有内容可记录。
2. 如何获取你需要的上下文数据
如果想记录SESSION、POST等请求数据,直接打印对应的超全局变量即可:
catch (RuntimeException | Exception $ex) { error_log("Login Page: ".$_SESSION['message']); // 记录POST数据 error_log("POST data: ".print_r($_POST, true)); // 记录SESSION数据 error_log("SESSION data: ".print_r($_SESSION, true)); }
3. 如何让debug_backtrace()生成有效栈信息
如果确实需要调用栈轨迹,把抛出异常的逻辑封装到函数或方法中即可,这样调用栈会包含函数调用记录:
function validateRequest() { if (empty($_SESSION['b']) || empty($_POST['d'])) { if(empty($_SESSION['b'])) { error_log("session appears empty. No b"); } if(empty($_POST['d'])) { error_log("POST appears empty. No d"); } throw new RuntimeException('Incorrect validation/form details given.'); } } try { validateRequest(); } catch (RuntimeException | Exception $ex) { error_log("Login Page: ".$_SESSION['message']); error_log("debug: ".print_r(debug_backtrace(), true)); }
4. 更推荐的异常追踪方式
直接使用异常对象自带的getTrace()方法,它记录的是抛出异常时的调用栈,比debug_backtrace()更准确,还能同时获取异常的基础信息:
catch (RuntimeException | Exception $ex) { error_log("Login Page: ".$_SESSION['message']); // 异常调用栈 error_log("Exception trace: ".print_r($ex->getTrace(), true)); // 异常基础详情 error_log("Exception info: ".$ex->getMessage()." | File: ".$ex->getFile()." | Line: ".$ex->getLine()); }
内容的提问来源于stack exchange,提问作者Mm-Art-In
相关产品推荐
相关产品推荐

