我想要创建一个调试函数,它可以转储有关执行上下文的信息以及其他一些信息。
在debug.php中,我有一个函数,它转储作为参数传递的任何内容。我感兴趣的是一种调用转储函数的方法,比如example.php,并让它返回调用上下文的文件名、行号和函数名。
1. <?php
2. function my_function(){
3. $var = 'My example';
4. dump( $var );
5. }
6. ?>example.php
我希望上面的函数输出:"example.php,my_function,4:我的示例“。
除了传递__FILE__、__FUNCTION__和__LINE__作为参数之外,还有这样做的吗?
发布于 2011-11-20 19:23:23
是的,你可以使用debug_backtrace()。
它以相反的顺序返回所有调用者和文件(跟踪也包括文件)的数组(最后是最高祖先)。因此调用方将是数组中的第一个:
$caller_info = next(debug_backtrace());发布于 2011-11-20 19:23:08
print_r(debug_backtrace());backtrace的输出是一个关联数组的数组,它为您要查找的这些常量命名。对于此示例代码,数组debug_backtrace()返回如下所示:
Array
(
[0] => Array
(
[file] => /t.php
[line] => 9
[function] => abc
[args] => Array
(
[0] => a
)
)
)发布于 2012-12-19 12:32:51
我也使用debug_backtrace,我试着处理不同的场景,这看起来可能太费时或者很糟糕,但是对我来说(构建我自己的小型mvc非常有用)。需要处理的场景示例:
所有这些场景都会影响debug_backtrace带来的结果,我的调试函数(在下面定义)试图处理这些场景。
每个函数/方法的定义如下
function my_func(){if(__DEBUG){dbg(debug_backtrace(),__CLASS__);}然后,当我想要生成最终代码时,我可以运行一个简单的脚本来替换if语句,例如
a="if(__DEBUG){dbg(debug_backtrace(),__CLASS__);}"
b="//replace_what_ever"
dir="/var/www/mydir/"
find $dir -name \*.inc -exec sed -i "s/$a/$b/g" {} \;
find $dir -name \*.php -exec sed -i "s/$a/$b/g" {} \;至于调试函数,它可以放在脚本的最末端,假设是在very和index.php,但是如果您已经为会话处理程序定义了一个类,那么最后一个命令将在该类的析构函数中执行。
因此,在大多数情况下,当发生错误时,您的调试函数会让您知道。但是,在发生致命错误时,由调试函数打印所创建/存储的结果(存储在某个数组中,此处为$dbg_log)的行将无法打印(例如,打印命令放在index.php的末尾)!在这种情况下,您需要手动处理程序(仅针对致命错误)来打印结果数组,我是这样做的:
register_shutdown_function('handleShutdown');
//Catch fatal errors
function handleShutdown() {
$error = error_get_last();
global $dbg_log;
echo "<pre>";
if(
$error['type'] === E_COMPILE_ERROR or
$error['type'] === E_ERROR or
$error['type'] === E_PARSE or
$error['type'] === E_CORE_ERROR or
$error['type'] === E_CORE_WARNING or
$error['type'] === E_RECOVERABLE_ERROR
)//we need to catch fatal errors under debug
{
//print_r($error); if you like
$dbg_log[] = " Tip: Start backward, the failing function (line) cannot echo a text put at the end of the function!";
$last = count($dbg_log)-1;
for($i=$last;$i>-1;$i--){
echo "$i: {$dbg_log[$i]} \n<br>";
}
}
}$dbg_log用于收集在全局上下文中定义的所有这些信息(参见下面)。
现在,我的调试函数是这样的:
define('__DEBUG', true); // Easily switch from/to debug mode
$dbg_log = array(); // Keep log of function calling sequence for debuging purposes
function dbg($tr, $callee_class){
global $dbg_log;
// If the file of the caller exists
if(isset($tr[0]['file'])){
$caller = $caller=$tr[0]["file"].':'.$tr[0]["line"]; // Then we can get its name and calling line
// If the caller is a function then it was a callee before so $tr[1] should exists
if(isset($tr[1])){
// If the caller is a class method
if(isset($tr[1]["class"])){
$caller = $tr[1]["class"]."whenever->".$caller=$tr[1]["function"].':'.$caller;
}
// Else
else{
$caller = $tr[1]["function"].$caller;
}
}
}
// Else this is an auto call by php compiler
else{
$caller = 'auto';
}
// Log the debug info
$dbg_log[] = 'Started: '.$callee_class.'::'.$tr[0]['function'].' by '.$caller;
}$tr (跟踪)数组包含debug_backtrace的结果,因为它们存在于被调用的功能中。另外一件事要提到的是,打电话的人在打电话之前总是一个卡莉!!
这些是$dbg_log数组的输出(在致命错误或正常退出时)所产生的一些真实的(对您来说毫无意义,尽管提供的整个信息是显而易见的)结果:
27: Started: Framework\registry::get by App\View\WebWindowOne->__construct:/var/www/MyProject/protected/view/WebWindowOne/WebWindowOne.php:36
26: Started: App\View\WebWindowOne::__construct by Application->AppStart:/var/www/MyProject/protected/Web_Application.php:240
25: Started: Application::AppStart by Application->__construct:/var/www/MyProject/protected/Web_Application.php:150
24: Started: Framework\riskManager::__construct by Application->{closure}:/var/www/MyProject/protected/Web_Application.php:52 有很多信息、行号、类等等,对于您定义的每个函数/方法,只需花费很少的努力(仅使用此function my_func(){if(__DEBUG){dbg(debug_backtrace(),__CLASS__);})。
https://stackoverflow.com/questions/8204005
复制相似问题