Представьте, что у меня есть следующая ситуация:
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(); ?>
в<?php include("Logger.static.php"); include("TestClass.class.php"); new TestClass(); ?>
в<?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. Есть идеи, как это исправить?
Вы можете использовать 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. }
debug_backtrace () может использоваться для трассировки в стек вызовов. Это может быть медленным, поэтому будьте осторожны с ним, если вы делаете много записей.
Если вы используете PHP 5.3, вы можете воспользоваться поздней статической привязкой и иметь метод базового класса log()
, и ваши дочерние классы могли бы вызвать его, но при этом сохранять статические ссылки на __FILE__
и __LINE__
.
Окончательный вариант будет просто передавать __FILE__
и __LINE__
в качестве параметров при вызове функции log()
.
Это старый вопрос, но, видя, как мое решение не здесь, я предоставлю его потомству
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)
.