Статьи

Отладка и профилирование PHP с помощью Xdebug

PHP является самым популярным языком для веб-разработки, но обычно его критиковали за то, что ему не хватало подходящего отладчика. Разработчики, использующие такие языки, как Java и C #, пользуются мощным набором средств отладки, часто интегрированных непосредственно со своими IDE. Но разобщенная природа веб-серверов и PHP IDE помешала нам использовать многие из этих инструментов. Мы вручную добавили операторы отладки в наш код … пока Xdebug не заполнил пустоту.

Xdebug — это бесплатный проект с открытым исходным кодом, разработанный Дериком Ретансом, и, возможно, одно из самых полезных расширений PHP. Он предоставляет не только базовую поддержку отладки, но и трассировку стека, профилирование, покрытие кода и т. Д. В этой статье вы узнаете, как установить и настроить Xdebug, как отладить ваше PHP-приложение из Netbeans и как прочитать отчет по профилированию в KCachegrind.

Установка и настройка Xdebug

Если вы используете XAMPP или MAMP, Xdebug поставляется предустановленным; вам просто нужно включить его в вашем php.ini . Если вы используете установку на основе пакетов на платформе, такой как Ubuntu, вы можете установить ее через менеджер пакетов с помощью команды, подобной apt-get install php5-xdebug .

Записи для Xdebug в моем php.ini выглядят так:

  [Xdebug]
 zend_extension = "/ Applications / MAMP / бен / php5.2 / Библиотека / PHP / расширения / нет отлаживать-не-ЗТС-20060613 / xdebug.so"
 xdebug.remote_enable = 1
 xdebug.remote_host = локальный
 xdebug.remote_port = 9000 

zend_extension указывает путь к модулю Xdebug. Значение xdebug.remote_enable переключает, является ли расширение активным или нет. xdebug.remote_host — это имя или IP-адрес вашей системы (здесь я указал localhost, потому что я работаю на одном компьютере, но значение может быть IP-адресом или именем хоста DNS, если вам нужно указать что-то другое для вашей настройки). xdebug.remote_port — это порт, на котором клиент прослушивает соединение из Xdebug (значение по умолчанию — 9000).

Когда вы используете Xdebug, важно убедиться, что вы не используете никакие другие расширения Zend, поскольку они могут конфликтовать с Xdebug.

Есть и другие варианты установки. На веб-сайте Xdebug есть простой мастер, который поможет вам в установке. Вы можете взять вывод phpinfo() или php –i и вставить его в текстовое поле, а мастер проанализирует конфигурацию вашего сервера и сообщит вам, как скомпилировать Xdebug для вашего компьютера.

Отладка

Чаще всего соблазнительно использовать var_dump() и exit / die() для отладки. Но проблема с этим подходом состоит в том, что вы должны изменить код для отладки; Вы должны помнить каждое место, куда вы добавляли выходные операторы, и удалять их после завершения отладки. Xdebug преодолевает это, позволяя вам приостанавливать выполнение вашего приложения в любом месте. Затем вы можете проверить значения переменных в этой области, чтобы лучше понять, что делает PHP.

Вы можете легко настроить Netbeans для работы в качестве клиента Xdebug. Откройте окно параметров (Инструменты> Параметры) и перейдите на вкладку отладки для раздела PHP. Введите порт отладки, указанный в php.ini и идентификатор сеанса, который вам нужно будет передать с запросами, которые вы хотите отладить. Теперь вы сможете запустить отладчик, нажав Отладка на вкладке инструментов.

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

Обратите внимание на строку URL XDEBUG_SESSION_START параметре XDEBUG_SESSION_START . Для запуска отладчика вы должны передать XDEBUG_SESSION_START в качестве параметра запроса (GET / POST) или XDEBUG_SESSION в качестве параметра cookie.

На панели инструментов отладки есть и другие полезные действия. Они есть:

  • Step over — перешагнуть текущую строку
  • Шаг в — Шаг в функцию (для не встроенных функций)
  • Step out — выйти из текущей функции

Вы можете добавить точки останова, щелкнув номер строки на полях редактора, а затем приостановив выполнение на них. Они могут быть удалены, нажав на них снова. В качестве альтернативы, перейдите в Window> Debugging> Breakpoints, где будут перечислены все точки останова в вашей программе, и вы можете выбрать / отменить выбор только тех, которые вам нужны.

Во время работы состояние переменных в текущей области видимости отображается в окне переменных. Он покажет значения локальных и $_COOKIE переменных, таких как $_COOKIE , $_GET , $_POST и $_SERVER . Вы можете наблюдать, как меняются их значения при прохождении через утверждения.

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

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

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

  xdebug.profiler_enable = 1
 xdebug.profiler_output_name = xdebug.out.% t
 xdebug.profiler_output_dir = / tmp
 xdebug.profiler_enable_trigger = 1 

Профилирование по умолчанию отключено в Xdebug, поэтому для его включения используется xdebug.profiler_enable . xdebug.profiler_output_name — это имя файла журнала профилировщика (спецификатор% t добавляет временную метку к имени файла; полный список спецификаторов см. в документации ). Xdebug сохраняет выходные данные профилирования в каталоге, указанном в xdebug.profiler_output_dir . Вы можете изменить это местоположение по своему выбору, но помните, что оно должно иметь разрешения на запись для учетной записи пользователя, под которой запускается скрипт PHP.

Профилирование снижает производительность, поскольку движок PHP должен просматривать каждый вызов функции и регистрировать его детали, поэтому вы не хотите запускать его все время. xdebug.profiler_enable_trigger указывает Xdebug выполнять профилирование только тогда, когда XDEBUG_PROFILE передается в качестве параметра GET или POST.

Файл журнала, созданный Xdebug, может быть маленьким или большим в зависимости от того, что делает приложение. Кроме того, это не очень удобно для читателей. Вы захотите использовать такие программы, как KCachegrind или Webgrind, чтобы просмотреть их. KCachegrind — это инструмент визуализации данных профиля для KDE, для работы которого требуется среда Unix, тогда как Webgrind — это веб-инструмент.

Открытие длинного файла профилирования в KCachegrind покажет стоимость каждого вызова функции, начиная с main() . Вот визуализация KCachegrind профилирования вывода функции для поиска факториала:

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

При оптимизации вашего кода вы должны искать области с самой высокой общей стоимостью. Чаще всего операции ввода-вывода будут иметь самую высокую стоимость. Не забудьте уменьшить их как можно больше. Ленивая загрузка файлов везде, где это имеет смысл.

Предположим, у вас есть класс с именем Orders который предоставит вам список всех заказов и их детали из вашего интернет-магазина.

 <?php class Orders { protected $db; public function __construct(PDO $db) { $this->db = $db; } public function getAll() { $orders = array(); $query = "SELECT * FROM orders"; $result = $this->db->query($query); while ($row = $result->fetch(PDO::FETCH_ASSOC)) { $row['details'] = $this->getDetails($row['orderId']); $orders[] = $row; } return $orders; } public function getDetails($orderId){ $details = array(); $result = $this->db->query("SELECT * FROM orderdetails WHERE orderId = " . $orderId); while ($row = $result->fetch(PDO::FETCH_ASSOC)) { $details[] = $row; } return $details; } } 

Этот класс имеет два метода: getAll() и getDetails() . Когда вы вызываете метод getAll() , он получает все записи из таблицы заказов и просматривает их, чтобы получить сведения обо всех записях.

Давайте посмотрим на информацию о профилировании.

Хотя абсолютные цифры не являются значимыми, поскольку они зависят от платформы и условий выполнения, вы получите представление об относительной стоимости различных функций. Обратите внимание, что некоторые функции вызываются сотни раз (что, конечно, плохо). Код не должен перебирать все заказы и получать детали каждого заказа в отдельности. Давайте перепишем getAll() чтобы вместо getAll() использовать JOIN.

 <?php pubilc function getAll() { $orders = array(); $query = "SELECT * FROM orders o JOIN orderdetails d ON o.orderId = od.Id ORDER BY o.orderId "; $result = $this->db->query($query); while($row =$result->fetch(PDO::FETCH_ASSOC)){ $orders[] = $row; } return $orders; } 

Теперь профилирование дает лучший результат, так как количество запросов уменьшилось. Кроме того, код больше не вызывает getDetails() .

Резюме

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

Его удаленная отладка позволяет вам проверять значения во время выполнения, не изменяя вашу программу, чтобы лучше понять, что делает PHP. Профилирование помогает выявить узкие места в вашем коде, чтобы вы могли оптимизировать его для повышения производительности.

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

Изображение через Fotolia