2009-09-02 49 views
1

澄清:如何获取传入当前对象的对象的类名或文件名?

我建立一个记录器类,可以让我轻松地记录消息:

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!'); 
} 
?> 

当我在itialize对象:

$this->log('------------- Initializing ------------- '.get_parent_class($this)); 

我要记录的对象(或文件)的名称与调用日志() - 在这种情况下,无论是

MyController
/path/to/MyController.php

我试过使用get_parent_class(),但当然这不起作用,因为记录器本身没有父类。

任何想法?十分感谢你的帮助!

亚历克斯·B

回答

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!'); 
    } 
} 
2

您预订购需要利用功能debug_backtrace()的。但是请注意,该函数的返回值并不是非常一致(即使它应该是 - 每个数组键都不存在,例如,表明该文件是未知的(eval'd code )或者与之前的堆栈帧相同)。这是所谓的这个人应该在索引0可用之前的最后一个函数:

$trace = debug_backtrace(); 
$calling_function = $trace[0]['function']; 
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" 
    } 
} 

所以,应该包括你想;-)


不过,这似乎是最好的,在我看来,解决方案是什么,会可以通过调用日志方法所需的信息...
(只是感觉更多...自然^^但这不是一个非常理性的意见,我想^^)

0

我碰到了(几乎)最后这个确切的问题晚。我正在使用debug_backtrace()(正如许多人已经提到的)来解决它。我需要知道包含调用某个函数的控制器的模块。由于我的控制器在类名称中包含模块名称,因此我只需从debug_backtrace()中获取返回值,然后explode()将其取回以获取模块名称。

Soulmerge对于并不总是一致的回报做出了很好的评价,但是如果您以某种方式构建您的代码,您肯定能够获得足够准确的回报。