Всем знакомо? =)
Такой вот маленький кошмарик хоть раз писал любой 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! Делаем выводы...
Несколько дампов подряд. Как не потеряться?
<?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();
Как видите, разобрать всю цепочку вызовов шаблона 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-запросы
-
и т.д.
Но пока что повременю. Хотелось бы послушать о том, как вы отлаживаете свой код? Прям тут, в комментариях. Кстати, если захочется продолжения — пишите.
Даешь меньше багов каждому!
Хе-хе :) чувствую я чуток повлиял на статью эту))))
Давно уже хотел опубликовать =)
— Хотелось бы послушать о том, как вы отлаживаете свой код?
— Хуяк-Хуяк и в продакшн! ©
---------
Отлаживал долгое время через встроенный инструмент отладки)) потом перешел на plgSystemHiddenDebug :) чтобы не пугать пользователей на продакшн.
Денис, подскажи. Вот все вроде работает, а вот профилирование нет . Не знаешь в чем может быть проблема?
точнее работает из теста. А вот как это все посмотреть на странице jbzoo ?
- Включить режим отладки в Joomla
- Подключить файл "class.jbdump.php"
- Убрать строку в media / zoo / applications / jbuniversal / framework / helpers / jbdebug.php Скрин - http://llfl.ru/ucu2k3 (по умолчанию насильно отключено по понятным причинам)
-------
Внешний вид профайлера настраивается тут https://github.com/smetdenis/jbdump/blob/master/class.jbdump.php#L57 Это сумма из этих констант - https://github.com/smetdenis/jbdump/blob/master/class.jbdump.php#L145-L150
Например, 20 - это вывод таблицы + суммарной информации.
JBDump пользовался ранее, пользуюсь и сейчас. Для меня он единственный инструмент, когда надо подогнать под себя что-нибудь в JBZoo. После последней статьи попробовал профилирование проекта вместе с ним - наглядность графика и информативность таблиц заметно превосходит штатные средства Joomla (правда таблица не интерактивная, вопреки фразе в описании). Буду ждать рассказа о всех 100500 чудесных свойствах JBDump.
P.S.
При работе с JBDump всегда отключаю function sql($select) из файла jbdump.php
Спасибо, рад.
Под "интерактивностью" таблицы я подразумевал сортировку значений. По сути ей больше ничего не нужно для удобства. Задача ведь проста - очень быстро оценить проблемное место.