想象一下我有以下情况:
File1.php
<?php
include("Function.php");
log("test");
?>
Function.php
<?php
function log($msg)
{
echo "";
}
?>
我想更改日志功能,以便产生以下内容:
test(文件:File1.php,行号:3)
那么,有什么方法可以获取PHP中执行当前函数的代码的文件名和行号?
用于积压使用评论的EDIT: 当我以面向对象的编程方式使用backlog时,我有以下情况。
的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行。任何想法如何解决这个问题?
答案 0 :(得分:84)
您可以使用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 :(得分:27)
debug_backtrace()可用于追溯调用堆栈。它可能很慢,所以如果你做了大量的日志记录就要小心。
如果您使用的是PHP 5.3,则可以利用late static binding并使用log()
的基类方法,并且您的子类可以调用它,但仍然保持对{{1的静态引用}和__FILE__
。
当您调用__LINE__
函数时,最后一个选项就是将__FILE__
和__LINE__
作为参数传递。
答案 2 :(得分: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 ) ));
你可以抛出/ catch来获得一个干净的堆栈跟踪,然后你需要查找包含这个文件的第一行(通常是调用它的地方)你也可以使用跟踪的索引如果你知道的话它,或功能。
异常堆栈跟踪与执行debug_backtrace(true)
几乎相同。