2009-08-09 45 views
41

想象我有以下情况:获取在PHP中执行当前函数的代码行和文件?

File1.php

<?php 
include("Function.php"); 
log("test"); 
?> 

Function.php

<?php 
function log($msg) 
{ 
    echo ""; 
} 
?> 

我想更改日志功能,因此,它会产生如下:

测试(文件:File1.php,行号:3)

那么,有什么方法可以获取在PHP中执行当前函数的代码的文件名和行号?

编辑积压使用评论: 当我使用我的面向对象的编程方式积压我有以下情况。

的index.php

<?php 
include("Logger.static.php"); 
include("TestClass.class.php"); 
new TestClass(); 
?> 

TestClass.class.php

<?php 
class TestClass 
{ 
    function __construct() 
    { 
    Logger::log("this is a test log message"); 
    } 
} 
?> 

Logger.static.php

<?php 
class Logger 
{ 
    static public function log($msg) 
    { 
    $bt = debug_backtrace(); 
    $caller = array_shift($bt); 
    echo $caller['file']; 
    echo $caller['line']; 
    } 
} 
?> 

这个例子将返回为文件 “的index.php” 和作为4号线,这是课程开始的地方。但是,它应该返回文件TestClass.class.php和行号6.任何想法如何解决这个问题?

回答

73

您可以使用debug_backtrace()。

http://us3.php.net/manual/en/function.debug-backtrace.php

所以,在你的日志功能,您将能够检索该日志函数被调用的文件名和行号。

我在我的日志记录类中使用了这种方法,它显着减少了获取有意义的日志数据所需的代码量。另一个好处是可读性。与字符串混合时,魔术常数会变得相当难看。

这里有一个简单的例子:

function log($msg) 
{ 
    $bt = debug_backtrace(); 
    $caller = array_shift($bt); 

    // echo $caller['file']; 
    // echo $caller['line']; 

    // do your logging stuff here.  
} 
+1

其实,有一个问题。我以面向对象的方式进行编码,并且它正在返回行和调用调用该函数的对象的脚本。相反,它应该给我包含的类的名称和该类文件中的行。任何想法? – Tom 2009-08-09 23:53:11

+0

你需要在这里更具体。你能告诉我你得到了什么以及你的期望吗? – 2009-08-10 07:32:55

+0

你好Lior Cohen,你能查看我编辑过的原文吗?我在那里详细解释了一切。谢谢! – Tom 2009-08-11 10:49:35

21

debug_backtrace()可用于追溯通过调用堆栈。它可能会很慢,所以如果你做了大量的日志记录,请小心。

如果你使用PHP 5.3,你可以利用late static binding并有log()一个基类的方法,你的子类可以称之为但仍保持静态引用到__FILE____LINE__

当您调用log()函数时,最后一个选项将仅作为参数传入__FILE____LINE__

+0

'__FILE__'和'__LINE__'可能的方式更有效,但它增加了代码的混乱。顺便说一句,也许正确的调试可以在需要时替换文件/行日志。 – christopheml 2009-08-11 10:52:38

+0

'debug_backtrace()'从'__LINE__'缓慢2次,但是这允许平均计算机在1 ms内完成100个呼叫,在强大的服务器上在1 ms内完成1000个呼叫。所以它可能并不那么慢。 – Enyby 2014-12-22 08:35:41

1

这是一个老问题,但看到我的解决方案是如何不在这里,我会为后人

 try{ 
     throw new Exception(); 
    }catch (Exception $e){ 
     $trace = $e->getTrace(); 
    } 

    $length = 0; 

    foreach ($trace as $t){ 
     if($t['file'] != __FILE__){ 
      break; 
     } 
     ++$length; 
    } 
    return array_slice($trace, ($length - count($trace))); 

你可以抛出/捕获它提供要获得干净的堆栈跟踪,那么您需要查找包含此文件的第一行(通常是从中调用它的位置),如果您知道该文件或函数,还可以使用跟踪的索引。

的异常堆栈跟踪几乎是一样的做debug_backtrace(true)

相关问题