Подтвердить что ты не робот

PHP debug_backtrace в производственном коде для получения информации о методе вызова?

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

Я думаю, что вы делаете это нормально.

Ответ 4

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

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

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

  • Функция foo() вызывает
  • Функция отражающая(), которая выполняет отладочную обратную трассировку и запросы
  • http://example.com/REST/ foo

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

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

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

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

Ответ 5

Правильный ответ: полностью ОК. Алан указывает на неэтичность 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 вокруг, или пытаясь угадать его из имен классов или уничтожить его, поместив его в глобальные переменные.

Для тех, кто интересуется временем, microtime был 2.7E-5. Достаточно быстро. Просто не помещайте это через некоторое время (1).

Ответ 6

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

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

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