PHP debug_backtrace в рабочем коде для получения информации о вызове метода? - PullRequest
24 голосов
/ 06 декабря 2008

Есть ли веская причина не использовать debug_backtrace с единственной целью определения класса, имени и списка параметров вызывающего метода? Не для отладки. У него есть слово «отладка» в названии функции, что заставляет меня чувствовать себя немного грязно, если я использую его таким образом, но это соответствует требованиям того, что мне нужно было сделать (одна функция, которую можно вызывать из многих мест необходимо вызвать вызывающий метод из другой системы). Это работает, но это все еще плохая идея? Если так, то почему?

Ответы [ 6 ]

16 голосов
/ 07 декабря 2008

Это выглядит немного грязно, но, как хорошо документировано, открыто и избито до смерти в других местах, PHP не является системой, разработанной для элегантности.

Одна очень запутанная причина , а не , чтобы использовать debug_backtrace для логики приложения, - это возможно, что какой-то будущий разработчик, работающий над PHP, может решить: «это просто функция отладки, производительность не имеет значения».

Если вас интересует «лучший» способ сделать это, вы, вероятно, можете использовать магические константы PHP для передачи вызывающего метода и имени класса, а затем использовать ReflectionMethod объект для извлечения любой другой информации, которая вам нужна.

Я ставлю лучше в кавычки, потому что, хотя это будет чище и правильнее, накладные расходы на создание экземпляра объекта Reflection могут быть больше, чем при использовании функции debug_backtrace.

16 голосов
/ 06 декабря 2008

Есть ли убедительная причина не использовать debug_backtrace с единственной целью определения класса, имени и списка вызывающего метода?

Да. Дело в том, что, как правило, это признак плохого дизайна, если ваш код требует такой тесной связи, что вызываемый должен иметь эту информацию о вызывающем абоненте. Поэтому, если вы чувствуете необходимость использовать эту информацию, вам, вероятно, следует пересмотреть свой дизайн.

Говоря прямо, вызываемый объект не должен иметь эту информацию для выполнения своей задачи. Исключения, конечно же, связаны с отладкой, ведением журнала и, в более общем смысле, с другими видами интроспекции кода (но даже там, остерегайтесь этого).

4 голосов
/ 06 декабря 2008

debug_backtrace - одна из функций обработки ошибок PHP. Руководство призывает пользователей определить свои собственные правила обработки ошибок, а также изменить способ регистрации ошибок. Это позволяет вам изменять и улучшать отчеты об ошибках в соответствии с вашими потребностями. Это также означает, что снижение производительности при использовании этих функций незначительно.

Я думаю, что вы делаете просто отлично.

3 голосов
/ 03 декабря 2015

Правильный ответ: полностью ОК . Алан указывает на не элегантность PHP, поэтому я не буду повторять его слова. Причина (не бойтесь) использовать debug_backtrace в коде времени выполнения состоит в том, что PHP в основном является языком без контекста. Каждая функция не знает и не может знать «намерение» вызывающего, не используя магические имена функций (например, в классе - например, __toString ()) с приведением типов. Давайте рассмотрим случай, когда у вас есть класс, в котором (в методе) вы хотите предоставить доступ к свойствам вызывающего (внешнего) класса. Это действительно грязно и склонно к ошибкам, которые можно передавать ($ this) через API функции. (Особенно, если вы хотите использовать array_map или call_user_func_array.)

, например

<?
class a {
 public $v = 'xyz';
 function __construct($x,$y)
 {
   $b = new b();
 }
}
class b {
 function __construct()
 {
   $start = microtime();
   $x = debug_backtrace();
   $end = microtime();
   echo ($end-$start) . "\n";
   print_r($x);
   $obj = $x[1]['object'];
   print_r($obj);
 }
}
$a = new a(1,2);
?>

debug_backtrace предоставит вам доступ к контексту класса a в __construct of b. Теперь вы можете передавать некоторые переменные состояния из текущего класса, не передавая $ this, не пытаясь угадать его по именам классов или запутав, поместив его в глобальные переменные.

Для тех, кто интересуется временем, микротайм был 2.7E-5. Достаточно быстро. Только не кладите это на некоторое время (1).

3 голосов
/ 07 декабря 2008

Вы сказали в комментарии

Задача вызываемого - вызвать тот же метод, который вызывал его на другом компьютере. Это позволяет избежать использования разных API-функций для каждого возможного источника, что значительно уменьшило объем кода в системе. Это все еще плохо

Итак, вы хотите сделать следующее:

  • Функция foo () звонки
  • Функция reflective () , которая выполняет отладку и запрашивает
  • http://example.com/REST/foo

Предполагая, конечно, что вы используете HTTP-запросы для отключения удаленного вызова.

Это немного странно. Если вы создаете систему с нуля, я бы посоветовал попытаться обойти ее. Если ты включаешь это в унаследованную систему, то, наверное, я понимаю.

Я бы посоветовал вам всегда быть более откровенным, когда можете. Использование интроспекции волшебного стека может сэкономить вам немного кода, но для другого разработчика ваш код будет полностью сбит с толку. Если это так, вы передаете имя класса и функции функции, которая ранее выполняла отражение. Тогда нет никакой двусмысленности в том, что происходит.

  • Функция foo () звонки
  • Функция Светоотражающий (__ CLASS__, __FUNCTION __) , который запрашивает
  • http://example.com/REST/foo
0 голосов
/ 03 июня 2010

Я думаю об использовании debug_backtrace для отладки операторов mysql. Чёрт возьми, гораздо проще определить ошибочные или медленные запросы, если в начале каждого запроса в журналах базы данных есть такой заголовок:

/*Called from /var/www/micimacko.php at line 28*/ SELECT count(*) FROM rofibeka;

Вопрос остается. Как насчет производительности / надежности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...