Отладка PHP приложений с xdebug

До погружения в возможности xdebug, давайте поговорим об установке. В Unix вы можете попробовать установить xdebug из библиотеки расширений PHP. Данный вид установки не работает на всех системах. Если так происходит в вашей системе, вы должны скомпилировать расширение xdebug из исходников. Но в начале попробуйте установку из PECL:

pecl install xdebug

Как было сказано выше, если установка из PECL не работает в вашей системе, вы должны скомпилировать xdebug из исходников. В дополнение к компилятору языка C, у вас должны быть соответствующие версии приложений для сборки (Autoconf, Automake и Libtool). Если их у вас нет, необходимо их установить..
К тому же в PHP есть две необходимые программы phpize и php-config, которые являются частями PHP, они также понадобятся для установки. Если вы не компилировали PHP из исходников, то возможно понадобится установить пакет разработки (php5-dev).
Обратите внимание, что phpize и php-config должны соответствовать используемой версии PHP, поэтому не копируйте их в свою систему из другой. Когда вы убедились, что все необходимые программы присутствуют, вы можете скачать и скомпилировать xdebug:

wget http://xdebug.org/link.php?url=xdebug201
tar -xzf xdebug-2.0.1.tgz
cd xdebug-2.0.1
phpize
./configure --enable-xdebug --with-php-config=/usr/bin/php-config
make
cp modules/xdebug.so /usr/lib/apache2/modules/xdebug.so


Путь к php-config может быть другим в вашей системе. В зависимости от настроек Apache вы должны скопировать xdebug.so в нужный каталог. Однако вместо копирования файла вы можете создать символическую ссылку на него.

Установка в Windows

Если вы пользуетесь Windows, вы можете скопировать скомпилированную DLL с xdebug.org. Выберете версию PHP, которую вы используете, и кликнете на соответствующей ссылке.
Я рекомендую сохранить скачанную DLL в каталог для расширений ext.

Активация расширения xdebug

Сейчас у вас есть готовое расширение xdebug, который является либо shared-объектом в Unix или DLL в Windows. Для его активации необходимо добавить запись в php.ini.

Для Windows: zend_extension_ts="c:\php\ext\php_xdebug-2.0.1-5.2.1.dll"
Для Unix: zend_extension="/usr/lib/apache2/modules/xdebug.so"


Путь к каталогам, в которых находятся расширения PHP и Apache могут быть другими на вашей системе. Убедитесь в том, что вы используете абсолютные пути.
Пожалуйста, обратите внимание, что в примере для Windows мы используем zend_extension_ts, что означает, что загружается потокобезопасное (thread-safe) расширение, в то время как для Unix, мы загружаем непотокобезовпасное расширение. В зависимости от настроек вашей системы, вы должны решать когда вам необходимо то или иное состояние. Если вы не знаете в каком режиме запущен ваш PHP, посмотрите на вкладку Thread Safety в выводе команды phpinfo().
Вы не сможете загружать другие расширения Zend порка работаете с xdebug, потому что они будут использовать тот же внутренний механизм движка Zend, что может привести к проблемам. Не все расширения Zend работают совместно с xdebug. Использовать xdebug предпочтительнее на машине разработчика, чем на продакшене из-за серьезных ограничений. Важное правило не использовать совместно с xdebug другие расширения PHP предназначенные для отладки.
Перестартовав ваш веб-сервер, потому что мы изменили php.ini, посмотрите вывод команды phpinfo() или запустите php -m в командной строке. В каждом из случаев, xdebug должен быть выведен дважды, один раз как расширение PHP, другой раз как расширение Zend

Zend

Будьте осторожны при обновлении PHP с установленным xdebug. Если поменяется внутреннее APIs в версиях PHP, новая версия PHP возможно не запустится или покажет странные ошибки. Если такое произойдет, временно отключите xdebug, дождитесь более новой версии PHP и xdebug и включите xdebug снова.
Для конфигурации xdebug существует несколько переключателей в php.ini, большинство из них имеет разумные значения по умолчанию, поэтому вы не должны беспокоиться о конфигурации xdebug. Мы рассмотрим самые важные параметры конфигурации.

Улучшенный вывод var_dump()

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

Вы можете настроить как именно xdebug должен формировать вывод функции var_dump() с помощью различных настроек в php.ini. Во-первых, вы можете изменить длину выводимой строки. Значение по умолчанию 512; более длинные строки обрезаются автоматически.
В зависимости от того выводить ли полностью строку или нет, зависит от ситуации и данных, с которыми вы работаете. Если вы работаете с большими строками, вывод функции var_dump() может быть слишком длинным и трудно читаемым, поэтому идея укорачивания строки выглядит достаточно приятной. В противоположность, если вы работаете со специфическими значениями, вы, скорее всего, заходите увидеть значение полностью.
Для изменения длины строки выводимой xdebug добавьте

xdebug.var_display_max_data=

в php.ini и перезапустите ваш веб-сервер. В качестве альтернативы, вы можете изменить эту настройку в своем скрипте используя функцию ini_set, вы можете добавить

ini_set('xdebug.var_display_max_data', );

в начале вашего скрипта. Проверьте, чтобы вызов ini_set был до первого вызова var_dump(). Конфигурация xdebug во время выполнения избавит вас от перезапуска веб-сервера каждый раз когда вы меняете php.ini и позволит более гибко его настраивать.
Вы также можете контролировать количество элементов массива и свойств объектов, которых будет выводить xdebug. Этого можно достигнуть модифицируя xdebug.var_display_max_children (значение по умолчанию 128). Этого значения будет вполне достаточно для отображения свойств вашего объекта, но если вы работаете с массивами, может быть необходимо увеличить значение..
Если вы работаете с вложенными объектами или массивами, вы можете модифицировать xdebug.var_display_max_depth. Эта настройка имеет значение по умолчанию 3, значит , что отобразиться три измерения в массиве и три уровня вложенности в объекте.
Вы также можете вывести значения суперглобальных переменных, используя функцию xdebug_dump_superglobals(). Так как суперглобальные массивы, особенно $_SERVER, - это массивы, содержащие большое количество значений, вы должны явно указать xdebug какой ключ массива вы хотите видеть. Чтобы сделать это установите xdebug.dump. , где это один из следующих имен GET, POST, SERVER, COOKIE, FILES, REQUEST или SESSION. Используйте ключи массивов, которые вы хотите вывести с помощью xdebug в качестве аргументов, если вы хотите выводить несколько значений, то перечислите их через запятую. Вы можете использовать * как шаблон для отображения ключей, который может особенно полезен для вывода $_GET и $_POST.
Используйте

ini_set('xdebug.dump.SERVER', 'HTTP_HOST, SERVER_NAME')

в вашем PHP скрипте или настройки xdebug.dump.SERVER=HTTP_HOST, SERVER_NAME в php.ini для отображения значений $_SERVER['HTTP_HOST'] и $_SERVER['SERVER_NAME']. Для отображения всех значений GET, которые были переданы в скрипт, используйте

xdebug.dump.GET=*

xdebug

По умолчанию xdebug не выводит неопределенные (undefined) переменные. Для того чтобы все же отображать неопределенные переменные, установите параметр xdebug.dump_undefined в On. Я советую установить этот параметр в on.

Более красивые сообщения об ошибках

xdebug также улучшает отображение ошибок в PHP автоматически отображая стек вызовов рядом с каждым сообщением об ошибке или предупреждением. Это список вызовов отображает историю вызова функций до момента возникновения сообщения об ошибке. В то время как программы на PHP становятся все более и более объектно-ориентированными, ошибки чаще всего случаются глубоко внутри библиотек. Список вызовов позволит вам быстро найти тот кусочек кода, в котором произошла ошибка, и откуда этот кусочек был вызван.
С версии 5.0 в PHP появилась функция debug_print_backtrace(), которая отображает список вызовов функций, но вы не можете вызвать эту функцию явно, всякий раз когда возникнет ошибка, что означает необходимость создания своего обработчика ошибок. Список вызовов, созданный xdebug, легко читаем в отличие от вывода функций PHP.
Подобно PHP, xdebug выводит ошибки только тогда, когда параметр display_erorrs установлен в On в php.ini.

xdebug

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

xdebug.show_local_vars=1

в php.ini. Вы также можете использовать ini_set.

xdebug

Итак, параметры php.in xdebug.var_display_max_data, debug.var_display_max_children и xdebug.var_display_max_depth, которые мы использовали выше для форматирования вывода команды var_dump() также влияют на формат вывода ошибок.
С помощью параметра xdebug.collect_params, вы можете настроить вывод информации о параметрах, которые передаются в функции. xdebug.collect_params имеет числовое значение: 0 – значит отсутствие информации, а 4 означает отображение названий переменных и полной информации по всем параметрам функций. Также доступны значения от 1 до 3, означающие различную детализацию в выводе отладочной информации.

xdebug

Здесь приведена конфигурация используемая для вывода скриншота:
 
xdebug.show_local_vars=On
xdebug.dump.SERVER=HTTP_HOST, SERVER_NAME
xdebug.dump_globals=On
xdebug.collect_params=4

Обратите внимание, что чем больше информации вы просите собрать для вас xdebug, тем больше памяти он будет потреблять, и тем больше будет время выполнения. Проверьте, что используете xdebug только для разработки, а не на боевых серверах. Неправильно использовать сообщения об ошибках в формате HTML на боевых серверах, не есть хорошо выводить информацию по логину и паролю к БД в том случае, если у вас не определена переменная .
В то время как суперглобальные переменные не изменяются во время выполнения (примечание переводчика – странное утверждение, видел достаточно много скриптов, в которых происходило их изменение, но не будем обсуждать это в контексте данной статьи), xdebug по умолчанию выводит их только вовремя первого возникновения сообщения об ошибке. Если вы хотите повторять их вывод каждый раз, воспользуйтесь следующей настройкой

xdebug.dump_once=Off

Обращаю внимание на то, что расширенный вывод сообщений об ошибках не работает, если вы определили собственный обработчик ошибок, используя register_error_handler(), все происходит из-за то, что xdebug использует тот же внутренний механизм. Если же вы хотите использовать собственный обработчик ошибок вы можете воспользоваться функцией xdebug_get_function_stack() для вывода списка вызова функций.
Объектно-ориентированный подход использует исключения. Так как исключения это не ошибки, xdebug не выводит список вызовов, если случилось исключение, за исключением тех случаев, когда такое исключение не перехватывается. Неперехваченное исключение это фатальная ошибка. Для того чтобы видеть вызов функций во время появления исключений используйте

 xdebug.show_exception_trace=On

Лимит рекурсии

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

xdebug.max_nesting_level=

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

Заключение

xdebug это маленький, но очень полезный инструмент для разработчика PHP, он должен быть установлен на каждую установку PHP, используемую для разработки. Не стоит использовать xdebug на боевых серверах, так как это мешает производительности.
Следующая статья будет посвящена Tracing PHP Applications with xdebug и будет переведена где-то в конце этой недели.

По материалам:  xdebug.ru

Возврат к списку

10
3.76