澄清:
我正在构建一个允许我轻松记录消息的Logger类:
lib.Logger.php:
<?php
class Logger {
private $handle;
public function __construct($log_name, $log_path) {
if ( ! is_dir($log_path))
throw new Exception('Log path does not exist.');
if ( ! in_array(strtolower(substr($log_name, 0, -4)), array('.log', '.txt')))
$log_name = "{$log_name}.log";
$this->handle = fopen("{$log_path}/{$log_name}", 'a');
$this->log('------------- Initializing ------------- '.get_parent_class($this));
}
// --------------------------------------------------------------------
public function __destruct() {
fclose($this->handle);
}
// --------------------------------------------------------------------
public function log($message) {
$time = date(DATE_RFC822);
$log = "[{$time}] {$message}\n";
fwrite($this->handle, $log);
}
}
?>
我称之为:
MyController.php:
<?php
class MyController extends Controller {
$logger = new Logger('testlog','/path/to/logs/');
$logger->log('Logs are fun!');
}
?>
初始化对象时:
$this->log('------------- Initializing ------------- '.get_parent_class($this));
我想记录调用log()的对象(或文件)的名称 - 在这种情况下,
MyController或
/path/to/MyController.php。
我尝试使用get_parent_class(),但当然这不起作用,因为Logger本身没有父类。
有什么想法吗?非常感谢你的帮助!
Alex B
答案 0 :(得分:3)
我想解决方案可能是使用debug_backtrace
。
给定的示例得到这样的回溯:
array(2) {
[0]=>
array(4) {
["file"] => string(10) "/tmp/a.php"
["line"] => int(10)
["function"] => string(6) "a_test"
["args"]=>
array(1) {
[0] => &string(6) "friend"
}
}
[1]=>
array(4) {
["file"] => string(10) "/tmp/b.php"
["line"] => int(2)
["args"] =>
array(1) {
[0] => string(10) "/tmp/a.php"
}
["function"] => string(12) "include_once"
}
}
所以,应该包括你想要的东西; - )
不过,在我看来,似乎最好的解决方案是传递调用日志方法时所需的信息......
(感觉更自然......自然^^但这不是一个非常理性的意见,我想^^)
答案 1 :(得分:2)
您将需要使用函数debug_backtrace()
。但请注意,该函数的返回值并不是非常一致(并非每个数组键始终存在,即使它应该是 - 索引文件可能会丢失,例如,表明文件未知(评估代码) )或与前一个堆栈帧相同)。在此之前调用的最后一个函数应该在索引0处可用:
$trace = debug_backtrace();
$calling_function = $trace[0]['function'];
答案 2 :(得分:1)
隐式处理此问题的唯一方法是捕获debug_backtrace的输出,就像其他人建议的那样。
如果您对明确的方法感兴趣,也许这可能就是
记录器中的
public function initialize( $context )
{
$logMessage = '------------- Initializing ------------- ';
if ( is_object( $context ) )
{
$logMessage .= get_class( $context );
} else {
// do something else?
}
$this->log( $logMessage );
}
然后
class MyController extends Controller
{
public function someFunc()
{
$logger = new Logger('testlog','/path/to/logs/');
$logger->initialize( $this );
$logger->log('Logs are fun!');
}
}
答案 3 :(得分:0)
昨晚我遇到(几乎)这个确切的问题。我正在使用debug_backtrace()
(正如许多其他人已经提到的那样)来解决它。我需要知道包含调用某个函数的控制器的模块。因为我的控制器在类名中包含模块名称,所以我只是从debug_backtrace
()获取返回值并使用explode()来获取模块名称。
Soulmerge对返回并不总是保持一致提出了一个很好的观点,但如果你以某种方式构建代码,你肯定能得到足够准确的回报。