2009-09-02 8 views
1

Pour clarifier:Comment obtenir le nom de classe ou le nom de fichier de l'objet qui a inséré l'objet courant?

Je construis une classe Logger qui me permet de me connecter facilement des messages:

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); 
    }  

} 

?> 

Et j'appelle cela en utilisant:

MyController.php:

<?php 
class MyController extends Controller { 
    $logger = new Logger('testlog','/path/to/logs/'); 
    $logger->log('Logs are fun!'); 
} 
?> 

Lorsque je dans itialize l'objet:

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

Je veux enregistrer le nom de l'objet (ou un fichier) qui appelle log() - dans ce cas, que ce soit

MyController
ou
/path/to/MyController.php
.

J'ai essayé d'utiliser get_parent_class(), mais bien sûr cela ne fonctionne pas car Logger n'a pas de classe parente en soi.

Des idées? Merci beaucoup pour l'aide!

Alex B

Répondre

1

La seule façon de gérer cela implicitement est de capturer la sortie de debug_backtrace comme les autres l'ont suggéré.

Si vous êtes intéressé par une approche explicite, peut-être cela pourrait être ce

dans Logger

public function initialize($context) 
{ 
    $logMessage = '------------- Initializing ------------- '; 
    if (is_object($context)) 
    { 
    $logMessage .= get_class($context); 
    } else { 
    // do something else? 
    } 
    $this->log($logMessage); 
} 

puis

class MyController extends Controller 
{ 
    public function someFunc() 
    { 
    $logger = new Logger('testlog','/path/to/logs/'); 
    $logger->initialize($this); 
    $logger->log('Logs are fun!'); 
    } 
} 
2

Vous willl besoin d'utiliser la fonction debug_backtrace(). Mais notez que la fonction n'est pas très cohérente dans sa valeur de retour (toutes les clés de tableau ne sont pas toujours présentes, même si elles devraient l'être - le fichier d'index peut manquer, par exemple, indiquant que le fichier est inconnu (code eval'd) ou le même que le cadre de pile précédent). La dernière fonction qui a été appelée avant que celui-ci devrait être disponible à l'index 0:

$trace = debug_backtrace(); 
$calling_function = $trace[0]['function']; 
3

Je suppose qu'une solution pourrait être d'utiliser debug_backtrace.

L'exemple donné obtient un backtrace comme ceci:

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" 
    } 
} 

Alors, devrait inclure ce que vous voulez ;-)


encore, la solution qui semble le meilleur, à mon avis, serait être de transmettre les informations nécessaires lors de l'appel de la méthode du journal ...
(Juste sent plus ... naturel ^^ Mais ce n'est pas une opinion très rationnelle, je suppose ^^)

0

je suis tombé (presque) ce problème exact dernière nuit. J'utilise debug_backtrace() (comme beaucoup d'autres l'ont déjà mentionné) pour le résoudre.J'avais besoin de connaître le module qui contient le contrôleur qui appelait une certaine fonction. Comme mes contrôleurs contiennent le nom du module dans le nom de la classe, j'ai simplement saisi le retour de debug_backtrace() et l'ai exploré() pour récupérer le nom du module. Soulmerge fait un bon point sur le rendement n'est pas toujours cohérent, mais si vous structurez votre code d'une certaine manière, vous pouvez certainement obtenir un retour assez précis.

Questions connexes