Как дебажить PHP

Материал из Umicms
Версия от 13:20, 31 июля 2018; Vitaliks (обсуждение | вклад) (¯\_(ツ)_/¯)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к:навигация, поиск

Отладка ошибки 500 при помощи register_shutdown_function

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

register_shutdown_function(function(){
	if (error_get_last()) {
		var_export(error_get_last());
	}
});

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

Документация по register_shutdown_function

Вывод данных отладки в браузере

Наиболее простой способ вывести любую переменную это функции print_r(), var_dump() и var_export()

print_r() - выводит структуру переменной в удобочитаемом виде

Документация по print_r

var_dump() - также выводит тип данных для всех переменных

Документация по var_dump

var_export() - выводит структуру переменно в формате пригодным для выполнения в PHP

Документация var_export

По умолчанию выводы этих функций используют '\n' в качестве переносов на новую строку.

Так как в браузере эти символы удаляются, то для того, чтобы результат было удобно читать, можно поместить его в тег <pre>

echo '<pre>';
print_r($var);
echo '</pre>';

или так

echo '<pre>' . print_r($var, true) . '</pre>';

В качестве второго аргумента для функций print_r() и var_export() можно указать true, если необходимо, чтобы функция возвращала результат, а не выводила его.

Код:

echo '<pre>';
print_r($variables['user']);
var_dump($variables['user']);
var_export($variables['user']);
echo '</pre>';

Результат вывода:

Array
(
    [id] => 3
    [type] => guest
)
array(2) {
  ["id"]=>
  int(3)
  ["type"]=>
  string(5) "guest"
}
array (
  'id' => 3,
  'type' => 'guest',
)

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

Документация по get_defined_vars

Вывод данных отладки в файл

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

Для записи данных отладки в файл нам поможет функция file_put_contents, можно использовать ее со следующими аргументами:

file_put_contents("umitest", print_r($variable, true)."\n", FILE_APPEND | LOCK_EX);

В результате выполнения данной функции рядом с файлом, из которого было запущено выполнение PHP (обычно это index.php в корне сайта), будет создан файл umitest в который запишется содержимое переменной $variable.

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

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

Можно вывести в файл все переменные, доступные в текущей области видимости:

file_put_contents("umitest", print_r(get_defined_vars(), true)."\n", FILE_APPEND | LOCK_EX);

или только некоторые из них

file_put_contents("umitest", print_r([$var1,$var2], true)."\n", FILE_APPEND | LOCK_EX);

Документация по file_put_contents

Получить стек вызова функции при помощи debug_backtrace

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

$debug_arr = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)

Также в качестве второго аргумента можно указать глубину стека.

Стек вызова можно вывести как в браузер:

echo '<pre>' . print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), true) . '</pre>';

так и записывать в файл:

file_put_contents("umitest", print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), true), FILE_APPEND | LOCK_EX);

Документация по debug_backtrace

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

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

$start = microtime(true);
// тут код время выполнения которого необходимо посчитать
$stop = microtime(true) - $start;
file_put_contents("umitest", print_r($stop, true)."\n", FILE_APPEND | LOCK_EX);

Документация по microtime