Отладка php в браузере

Обновлено: 04.07.2024

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

__FILE__ - это волшебная константа PHP которая всегда содержит имя текущего файла.

__LINE__ - это волшебная константа PHP которая всегда содержит номер строки в файле в котором она была вызвана.

Эти константы рекомендуется добавлять в вывод по нескольким причинам:

1) Удобство отслеживания из какого файла и строки в нем была сделана запись

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

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

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

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

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

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

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

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

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

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

Получить расположение используемого класса, метода или функции

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

Информация о функции

Этот код запишет в файл umitest путь до файла и номер строки в нем в которой находится функция 'function_name'.

Информация о классе

Этот код запишет в файл umitest путь до файла и номер строки в нем в которой находится класс 'class_name'.

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

Этот код запишет в файл umitest путь до файла и номер строки в нем в которой находится метод 'method_name' класса 'class_name'.

Первым аргументом при создании ReflectionMethod можно передавать не только имя класса, но и его экземпляр, например:

Обратите внимание, что в данном случае в файле задан namespace 'DebugNamespace', поэтому при получении экземпляра класса \ReflectionMethod необходимо наличие косой черты в начале иначе произойдет ошибка: Ошибка (Error): Class 'DebugNamespace\ReflectionMethod' not found

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

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

Настройка отладки php-кода при помощи Xdebug

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

В этой статье будет рассмотрена отладка PHP с помощью связки Xdebug и VSCode. Если вы пользуетесь PHPStorm, то проблем тоже не будет — настройка выполняется даже проще и быстрее.

Возможности Xdebug

Xdebug — это расширение для PHP, которое позволяет использовать удаленный отладчик в IDE через брейк-пойнты. С его помощью вы можете отслеживать значения переменных. Как итог — ошибки в коде обнаруживаются быстрее, чем при использовании error_log, print_r и var_dump.

Еще одна полезная функция — трассировка стека. Она выводит подробный путь, который привел приложение к ошибке. Он содержит параметры, переданные в функцию. Xdebug также можно использовать как профайлер для поиска узких мест кода. Если добавить внешние инструменты, то получится визуализировать графики производительности. Например, можно использовать WebGrind — набор PHP-скриптов для удобного вывода статистики прямо в браузере.

Кроме того, с помощью Xdebug вы можете проследить, какая часть кода выполняется в процессе запроса. Это дает информацию о том, как хорошо код покрыт тестами.

Подключение Xdebug

Для работы Xdebug PHP должен быть в режиме CGI. Посмотрим на примере хостинга Timeweb, как его включить.

Подключаемся к серверу через SSH. Можно использовать консоль в панели управления Timeweb.

Переходим в папку cd-bin сайта:

Создаем символическую ссылку командой:

Остаемся в директории cgi-bin и копируем файл php.ini:

Добавляем в файл .htaccess сайта две строки:

Теперь мы можем управлять параметрами PHP директивами в файле php.ini. Он находится в папке cgi-bin. Открываем его и вставляем в конце следующие строки:

Если указанный порт занят, укажите другой. Можно использовать стандартный для Xdebug — 9000. В качестве idekey я указал VSCODE. Если будете настраивать конфигурацию для PHPStorm, впишите его.

Настройка PHP для Xdebug

Чтобы проверить, работает ли Xdebug, создадим в корне сайта файл Myfile.php со следующим содержимым:

Открываем файл в браузере и проверяем, что все параметры указаны верно.

Организация удаленного подключения

Чтобы выполнять PHP Debug на локальной машине, нужно настроить связь IDE и сервера через SSH-туннель.

На Linux все выполняется парой команд.

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

На Linux туннель создается командой:

На Windows туннель настраивается через утилиту PuTTY.

  1. На вкладке Session указываем имя сервера и номер порта 1024. Проверяем, чтобы был отмечен протокол SSH.
  2. Переходим в раздел Connection — Data. Указываем логин.
  3. Переходим в раздел Connection — SSH — Tunnels. Указываем параметры так, как указано на скриншоте. Номер порта пишем тот, который используется в конфигурации PHP на сервере.
  4. Возвращаемся в раздел Session и нажимаем на кнопку Open. Подтверждаем корректность ключей (только первый раз).

Сессия сохранится под тем именем, которое мы указали в разделе Session. В дальнейшем нужно будет просто запускать ее заново.

Настройка VSCode

Чтобы работать с Xdebug в VSCode, установим два расширения: Sync-Rsync и PHP Debug. Первое нужно для работы с удаленным сервером, второе — для отладки скриптов.

  1. Открываем в VSCode раздел Extensions (можно использовать сочетание клавиш Ctrl+Shift+X).
  2. Находим и устанавливаем расширение Sync-Rsync.
  3. Находим и устанавливаем расширение PHP Debug.

После установки расширений создаем на локальной машине пустую папку и открываем ее через VSCode: «Файл» — «Открыть папку».

Добавляем подпапку .vscode, создаем внутри нее файл settings.json и прописываем в нем настройки для Sync-Rsync.

Путь /home/user/.ssh/id_rsa — это место, где лежит файл с закрытой частью SSH-ключа.

После сохранения файла settings.json нажимаем в VSCode F1, выполняем команду Sync Remote to Local. В локальную папку, указанную в настройках, скопируются все файлы с сервера.

Синхронизация с сервером

Затем нажимаем на иконку отладки и на шестеренку. В папке .vscode появится файл launch.json. В него тоже нужно внести изменения:

На этом настройка IDE завершена. Можно приступать к тестированию кода.

Debug кода

Мы настроили среду, теперь разберемся, как пользоваться Xdebug.

  1. Изменим содержимое файла Myfile.php, который мы создали при подключении отладчика. Добавим в него функцию, которую хотим проверит ь.
  2. Чтобы загрузить измененный файл на сервер, нажимаем на клавишу F1 и выполняем команду Sync-Rsync: Sync Local to Remote.
  3. Открываем файл в браузере и проверяем, что синхронизация работает.
  4. Расставляем в VSCode брейк-пойнты, которые нужны для отладки.

Переходим в режим «Отладка» и проверяем, что выделен пункт Listen for XDebug. Нажимаем на зеленый треугольник или на клавишу F5.

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

Отладчик Xdebug

Профилирование с визуализацией результатов

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

  1. Скачиваем WebGrind с GitHub.
  2. Загружаем архив на сервер и распаковываем файлы в корне сайта.
  3. Создаем папку, в которой будут храниться логи.
  4. Добавляем в файл php.ini две директивы:

Затем нужно открыть файл config.php, который находится в распакованной папке webgrind-master. В нем отредактируем две строки:

Функции можно скрывать или раскрывать, чтобы посмотреть развернутую статистику. Инструмент также умеет отображать графы вызова функций — для этого используется режим Show Call Graph.

Вывод: когда использовать Xdebug?

Xdebug существенно упрощает отладку PHP-кода. Конечно, если ваш текущий инструментарий удовлетворяет все потребности в поиске багов, то устанавливать дополнительное расширение смысла нет. Но, как показывает практика, без Xdebug сложно провести правильное модульное тестирование или отладку через удаленные брейк-пойнты с возможностью пошаговой проверки кода.

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

Тестирование

PHPUnit

PHPUnit - инструмент для тестирования, похожий на JUnit (который используется для тестирования Java). Он дает возможность создавать собственные юнит-тесты и выводить результаты в нескольких форматах. Сейчас это один из самых популярных фреймворков для юнит-тестирования в PHP. PHPUnit отлично подойдет для тестирования масштабируемости.

Selenium

Selenium - это легковесный фреймворк для тестирования с открытым исходным кодом. Он позволяет создавать UI-тесты на любом языке программирования. Совместим с большинством браузеров и отлично работает на Windows, Linux и macOS.

Отладка

Xdebug

Начиная с 2002 года (года запуска), Xdebug является одним из самых надежных инструментов PHP-разработчика. Он позволяет профилировать и отлаживать PHP-скрипты. Xdebug доступен в качестве плагина для Eclipse, PHPDesigner, а также совместим с многими другими инструментами разработки.

DebugBar

DebugBar - опенсорс-инструмент, который будет полезен любому разработчику, так как позволяет отслеживать в том числе ошибки в HTML и JS. Также DebugBar дает возможность мониторить сетевой трафик, оценивать качество JS-кода и инспектировать стили.

MacGDBp

Как понятно уже из названия, MacGDBp используется для отладки PHP на Маке. Вместе с расширением Xdebug дает возможность работать с локальными переменными и выводить стеки в интерфейсе macOS.

Безопасность

RIPS

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

Securimage

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

Мониторинг

Retrace

Retrace используется для отслеживания производительности. Также имеет функцию, позволяющую оперативно отслеживать ошибки и баги. Решить, стоит ли платить за этот продукт, можно в течение бесплатного 14-дневного периода.

New Relic APM

New Relic похож на Retrace и тоже дает возможность отслеживать производительность вашего PHP-приложения. Помимо этого, New Relic позволяет собирать данные пользователей, которые можно использовать для улучшения UX.

AppOptics

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

Каждая метка выглядит примерно так

Вы можете не ставить exit(), если абсолютно уверены в том, что код не обновляет страницу после вывода (нет рефреша).

Дальнейшие действия могут быть следующими:

Общее правило: продвигайтесь по коду очень медленно, стараясь не пропустить того момента, где таится баг. Старайтесь чаще использовать метод половинного деления.

Вывод значений переменных

Но что толку от того, что интерпретатор дошёл или не дошёл до какого-то места? Малоинформативно. Давайте добавим больше жизни!

Для того, чтобы увидеть содержимое переменной, используем print_r($var); или print_r($obj->var) если нужно посмотреть содержимое свойства конкретного объекта. Для того, чтобы увидеть значение true или false, используем var_dump(). Тут необходимо пояснить кое-что. Функция print_r() специально была придумана для того, чтобы красиво выводить значения разных типов. Причём она выводит и целые, и строки, и массивы и даже объекты. А вот true и false она не выводит, то есть вывод всегда будет равен пустой строке. Тут на помощь приходит var_dump(), который выводит точное значение и тип этого значения.

Использовать var_dump() везде я не рекомендую. Вывод, им генерируемый, выглядит намного запутаннее, чем вывод от print_r().

Итого, вот как будет выглядеть наша информативная метка:

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

Замер времени выполнения части кода

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

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

При этом после метки мы увидим время, потраченное на выполнение кода в секундах. Часто вы будете видеть что-то типа такого: 1.233433E-05, это инженерная форма записи очень малых и очень больших чисел. Можно привести её в нормальный вид, добавив функцию sprintf():

Немного больше кода, но зато вы будете видеть нормальные числа вроде 0.000012, т.е. 12 микросекунд.

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

Спасибо за внимание, не забудьте подписаться, чтобы не пропустить очередную статью!

Читайте также: