Радость отладки с JBDump или почему print_r ужасен

10.0/10 оценка (4 голосов)

Каждый, кто хоть раз работал с PHP, знает функцию print_r(). И любой видел, какую портянку «неизвестно чего» может выдать эта чудо-функция. Особенно, если почувствует рекурсию. Удобной отладкой это никак не назвать...

Радость отладки с JBDump или почему print_r ужасен

Всем знакомо? =)

Такой вот маленький кошмарик хоть раз писал любой php-программист.

<?php 
function myLoveDump($data) {
   echo '<pre>';
   print_r ($data); // var_dump ($data);
   echo '</pre>';
}

Надеюсь, вы не считаете «это» вершиной совершенства и невероятным удобством?

print_r — Почему это мерзко и неудобно?

Конечно каждый сходит с ума по своему. И сейчас я расскажу, почему мне не нравится этот способ сумасшествия.

Допустим, у меня есть объект, который содержит в себе несколько публичных и скрытых свойств. Какие-то свойства — это тоже объекты. Вполне типичная ситуация для любой CMS. Делаем myLoveDump($var); и ...

  • Ненавижу длинную портянку слабо отформатированных данных. Это время, это бесит!

  • die() нужно писать самому... ? каждый раз...

  • Дамп честно распечатает все вложенные объекты и скорее всего где-нибудь уйдет в рекурсию. Для этого всего лишь стоит напороться на глобальный объект (подключение к базе данных, например).

  • Зачем я вижу скрытые переменные? Конечно иногда это бывает полезно, но не в повседневной жизни.

  • Не видно типов переменных, длинны массивов, строк и т.д.

  • Нельзя изменить формат вывода. Допустим, я хочу сделать дамп в файл, потому что скрипт выполняет платежный робот.

  • Бывают вынужденные моменты, когда нужно проверить работу на продакшене. Тогда отладку хочу видеть только я, а не все подряд. Переменной JBDump.

  • У меня 10 разных дампов в разных местах. Как я узнаю какой и за что отвечает? Хотелось бы опциональный лейбл для переменной, а еще лучше — точное место вызова дампа. Ну чтобы не потерять его.

  • Я конечно капитаню, но единственная вещь которую умеет myLoveDump — это дамп. Слабовато для инструмента отладки. Еще бы хотелось, например, профайлер, логгер, красивый бэктрейс и все все все, и главное в одном флаконе.

Что бы хотелось видеть?

А хочется, как всегда, обычного человеческого тепла и счастья :)

  • Вложенность прятать и показывать только если хочется.

  • Простейший интерактив, например, сворачивать блоки.

  • Показывать только те переменные, к которым я имею доступ.

  • Не уходить на глубину более 3-4 уровней.

  • Автоматический die, который отключается в 2 нажатия.

  • Увидеть тип переменной. Кому как, а мне это крайне важно даже в PHP.

  • Хочу определять тип переменной по цвету, чтобы не тратить время на чтение.

  • Если это объект, то не плохо бы видеть список публичных методов. Это удобно в системах, с которым я слабо знаком.

  • Я хочу легко выставлять уровень доступа, например, по IP.

  • Хочется легко отправлять переменную в лог-файл или даже на почту.

Ну и раз пошла такая пьянка, то...

  • Профайлер, который выведет статистику по времени и памяти, количеству вызовов функций.

  • Красивый бэктрейс, т.к. не всегда понятно кто и откуда вызвал функцию.

  • Создавать отладчик как объект, где аргумент — это набор параметров, например, список разрешенных IP или путь до лог файла. Тогда можно использовать его как независимую библиотеку в любой системе.

  • Я хочу только один файл, который быстро закинул, подключил и начал работу. Без каких-либо болей с конфигурацией.

Красиво глаголишь, к чему это все... ?

Всем заинтересованным советую посмотреть класс JBDump, который уже сейчас в себе реализовал все эти хотелки и даже больше.

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

Как использовать JBDump ?

Установка

Все просто. Сводится к тому, что нужно подключить один файл с классом любым удобным способом. Лично я для локальных сайтов предпочитаю использовать php.ini и auto_prepend_file.

Типичный дамп

Допустим, у меня есть произвольная переменная и я хочу посмотреть что там, со всеми потрохами и вложенностями.

<?php 
// Делаем дамп всего $GLOBALS
jbdump($GLOBALS);

Заметьте, внизу видно строку вызова и JBDump сам вызвал die() - мелочь, а приятно. К сведению, вывод занял лишь 0,03 секунды + 250Кб памяти. И это посреди шаблона Joomla, переменная $GLOBALS с глубиной вложенности — 4. print_r сделал тоже самое только через 21 секунду, съел всего-то 94Mb! Делаем выводы...

Вложенности в JBDump

Несколько дампов подряд. Как не потеряться?

<?php 
jbdump($this, 0); // второй аргумент отключит die()
jbdump('qwerty', 0, 'строчка'); // третий аргумент - это название дампа, чтобы не путаться
jbdump(-0.123); // по умолчанию будет авто-die

Мы увидим три аккуратных сообщения. Первый можно развернуть, второй - именованный, после третьего PHP покорно «умер».

Несколько дампов подряд

Сохраняем переменную в файл

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

В случае с JBDump запись в файл — это лишь одна строка. Формат логов настраивается.

<?php 
jbdump::log(null, 'undef'); // пустая переменная и метка лога “undef”
jbdump::log(false, 'Bool'); // булево значение
jbdump::log('qwerrrrrrty'); // какая-то строка
jbdump::log($_REQUEST); // массив реквеста

Запись в файле одной строкой

Чтобы записать в лог мне не нужно задумываться:

  • каким образом происходит сохранение (весь этот нудный процесс открытия/закрытия, проверки прав, дописывания снизу и т.д.).

  • куда сохранится мой лог-файл (по умолчанию /logs/<текущая дата>.php).

  • о формате записи (как видите есть точное время, IP и даже место вызова).

  • о защите чтения извне.

Не нужно отвлекаться от работы - минимум усилий в очередной рутине.

Красивый бэктрейс

В жизни каждого программиста бывают случаи, когда есть функция и не понятно кто её вызывает и почему. Самый простой способ разобраться с негодяем — сделать бэктрейс. К сожалению, в PHP debug_backtrace() - мягко говоря, ужасен.

Вот мой вариант

<?php 
jbdump::trace();

Простой backtrace

Как видите, разобрать всю цепочку вызовов шаблона Joomla очень и очень просто.

Профилирование

К моему великому разочарованию, не все джумлаводы понимают суть этого слова. А все довольно просто — это, грубо говоря, процесс поиска медленного или прожорливого участка кода. На глазок такое не определить. Смотрим пример — создается огромный массив, он съедает память, затем опустошает её. Делаем измерения.

<?php 
// никакой специальной инициализации  

JBDump::mark('start loop');
$bigArray = array( 0 => 0);
for ($i=1; $i < 10000; $i++) { $bigArray[$i] = $i+@$bigArray[$i-1]; }
JBDump::mark('finish loop');

unset($bigArray);
JBDump::mark('unset $bigArray');

JBDump::mark('start loop #2');
   for ($i=0; $i < 1000000; $i++) {}
JBDump::mark('finish loop #2');

JBDump::mark('start loop #3');
   $j = 0;  for ($i=0; $i < 1000000; $i++) { $j++;}
JBDump::mark('finish loop #3');  

// Все. Скрипт сам(!) выведет результаты в конце работы PHP.

На выходе можно получить интерактивную табличку

Интерактивная таблица

или график с подсказками. Синий — это сумма, красный — это дельта между последними точками. Вот пример изменений по времени

График с подсказками

А это измерения используемой памяти

Измерения используемой памяти

И даже все добро можно сложить в отдельный файл

Отдельный файл для памяти

Бонус. Краткая статистика профилирования в конце

Статистика профилирования

Весь интерактив строится с помощью Google Charts (внешний скрипт). Формат вывод легко настраивается через параметры класса.

Как связать его с JBZoo ?

Так как большая часть нашего конструктора была разработана в обнимку с JBDump, то мы не удержались и сделали скрытую интеграцию с помощью хелпера jbdebug.

В основном это полезно, когда кто-то говорит, что его сайт тормозит. С помощью специального метода mark() мы подробно измеряем статистику работы всего компонента. Для этого нужно лишь раскомментировать строку в конструкторе хелпера и подключить jbdump. После этого внизу выводится таблица из профайлера. Буквально через 15 секунд можно увидеть подробную статистику сайта.

А вы слышали о xDebug+var_dump ?

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

Не устраивает он по ряду причин:

  • Его нельзя подключить/отключить по быстрому — это модуль. А это важно!

  • Его никогда не будет на шаред хостинге (и вообще в любом продакшене).

  • Он ужасно сильно тормозит весь PHP и даже роняет его.

  • Есть ряд несовместимостей с другими модулями PHP.

  • Вывод ошибок и трейсов — ужасен.

  • Внешний вид не настраивается. По сути это раскрашенный print_r

По большому счету у него иное предназначение и не нужно путать теплый myLoveDump (JBDump) с мягким xDebug. Это совершенно разные вещи и для разных целей.

Вместо заключения

JBDump — это не просто скрипт, который умеет отлаживать все и вся и там не просто так живет 100500 функций. Каждая из них появилась в какой-то определенный момент жизни. Просто потому что стала нужна.

Учитывая возраст этого скрипта (в районе 5-6 лет) и длинную историю развития, то могу смело заявить — это невероятно удобно! Работает как часы. Под постом можн найти ссылки на тесты и дополнительную документацию.

Все, что нужно — это подключить в проект 1 файл и пользоваться!

Конечно, еще хотелось бы рассказать вам о разных плюшках внутри JBDump, вроде:

  • SQL и JSON — дампы

  • Шаблонизация дампов

  • Работа с AJAX

  • Перехват ошибок и исключений

  • Простые и сложные счетчики

  • Рендер массивов PHP

  • Почтовые функции

  • Проверка файлов и папок

  • Работа с отражениями (reflection) классов и функций

  • Информация о системе

  • Разбор ссылок

  • HTTP-запросы

  • и т.д.

Но пока что повременю. Хотелось бы послушать о том, как вы отлаживаете свой код? Прям тут, в комментариях. Кстати, если захочется продолжения — пишите.

Даешь меньше багов каждому!

10.0 2417
jbdump, xdebug, наши проекты, отладка, Шибко умные мысли
  • CB9TOIIIA
    24 Июнь 2015 at 17:13
     ↑  +1  ↓  Ответить

    Хе-хе :) чувствую я чуток повлиял на статью эту))))

    • SmetDenis
      SmetDenis (admin)
      24 Июнь 2015 at 17:18
       ↑  0  ↓  Ответить

      Давно уже хотел опубликовать =)

  • CB9TOIIIA
    24 Июнь 2015 at 17:20
     ↑  +5  ↓  Ответить

    — Хотелось бы послушать о том, как вы отлаживаете свой код?

    — Хуяк-Хуяк и в продакшн! ©

    ---------

    Отлаживал долгое время через встроенный инструмент отладки)) потом перешел на plgSystemHiddenDebug :) чтобы не пугать пользователей на продакшн.

  • Антон
    25 Июнь 2015 at 17:51
     ↑  0  ↓  Ответить

    Денис, подскажи. Вот все вроде работает, а вот профилирование нет . Не знаешь в чем может быть проблема?

  • Юрий
    Юрий
    27 Июнь 2015 at 04:17
     ↑  0  ↓  Ответить

    JBDump пользовался ранее, пользуюсь и сейчас. Для меня он единственный инструмент, когда надо подогнать под себя что-нибудь в JBZoo. После последней статьи попробовал профилирование проекта вместе с ним - наглядность графика и информативность таблиц заметно превосходит штатные средства Joomla (правда таблица не интерактивная, вопреки фразе в описании). Буду ждать рассказа о всех 100500 чудесных свойствах JBDump.

    P.S.

    При работе с JBDump всегда отключаю function sql($select) из файла jbdump.php

    • SmetDenis
      SmetDenis (admin)
      27 Июнь 2015 at 14:38
       ↑  0  ↓  Ответить

      Спасибо, рад.

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

Оставить комментарий