Привет, меня зовут Ваня, я работаю PHP-разработчиком в Санкт-Петербургском электротехническом университете ЛЭТИ. Профайлинг приложений важный этап перед релизом ресурсоёмкой фичи, везде трубят про удобную отладку PHP-приложений при помощи XDebug и PHPStorm, однако напрочь забывают про замеры времени операций, которые, порой, превышают те самые 3 секунды, которые пользователь будет ждать на странице. Если у Вас есть метод API, который долго работает, самое время его проверить профайлером XDebug, а PHPStorm поможет красиво визуализировать и изучить файл профиля.
Я не буду писать про настройку XDebug вместе с Docker контейнером и Laravel Sail, потому что про это есть тонна статей, в том числе и на русском. Однако, эта статья предполагает, что у Вас есть настроенный XDebug в связке с PHPStorm в Docker контейнере или другой среде.
Заводим профайлер в XDebug
В минимальной настройке нам необходимо дополнить список включенных режимов режимом profile. Если Вы используете Laravel Sail, то можно изменить переменную среды SAIL_XDEBUG_MODE
в файле .env
, или напрямую изменить режимы в конфигурационном файле PHP. Режимы указываются параметром xdebug.mode
через запятую. Пример: xdebug.mode=develop,debug,profile
.
По умолчанию файл профайлинга сохраняется в директорию /tmp
, чтобы нам было удобнее давайте изменим директорию сохранения на /var/www/html
(для Laravel Sail эта директория монтируется к директории проекта), за это отвечает конфигурация xdebug.output_dir=/var/www/html
.
Рекомендую добавить в
.gitignore
все выходные файлы:/cachegrind.out*
.
Давайте теперь проверим нашу настройку, которая по итогу выглядит как-то так:
[XDebug]
xdebug.mode = develop,debug,profile
xdebug.start_with_request = yes
xdebug.discover_client_host = true
xdebug.client_host = host.docker.internal
xdebug.client_port = 9003
xdebug.idekey = PHPSTORM
xdebug.output_dir = /var/www/html
Просмотр профайла в PHPStorm
Перейдите на страницу в браузере, которую хотите изучить профайлером. После полной загрузки в корне проекта у нас создался файл cachegrind.out.<какое-то число>.gz
, давайте изучим его через инструмент для просмотра в PHPStorm. Честно говоря не знаю, где он находится в меню, поэтому воспользуемся сочетанием клавиш для вызова окна поиска действий Ctrl+Shift+A
. Ищем “XDebug Profiler” и заходим в него.
![Диалоговое окно поиска действий Диалоговое окно поиска действий](https://habrastorage.org/getpro/habr/upload_files/34f/029/bb1/34f029bb1ffcd6e7e6557c71446783bc.png)
Можете нажать Ctrl+2
чтобы сразу перейти в директорию проекта. Выбираем наш cachegrind.out.<какое-то число>.gz
и видим что профайла необходимого метода нет, только server.php.
![Наш server.php и больше ничего Наш server.php и больше ничего](https://habrastorage.org/getpro/habr/upload_files/6ef/6ec/fad/6ef6ecfad0419796d537e4c88a73aebd.png)
На этом моменте я немного расстроился, подумал, что с Laravel профайлер XDebug нормально не работает. Какое-то время пришлось изучать проблему, на StackOverflow была такая же проблема, однако к ней не было ни единого ответа. Через какое-то время я понял, что дело в файле и настройках XDebug.
Немного изменяем конфигурацию профайлера
И так, чтобы всё работало как нам необходимо, нужно понять в чём же проблема. Если изучить логи команды php artisan serve
, то мы увидим два запроса:
2024-01-23 22:44:56 ................................................... ~ 0s
2024-01-23 22:44:56 /favicon.ico ...................................... ~ 0s
Здесь и кроется ответ. Дело в том, что artisan команда serve запускает сервер PHP для разработки в одном потоке, а цифра в файле cachegrind.out
означает идентификатор процесса (PID). Так как все запросы идут через один процесс – в файл постоянно перезаписывается результат профайлинга последнего запроса. Решение простейшее: нужно изменить имя выходного файла при помощи конфигурации xdebug.profiler_output_name
. Я установил значение cachegrind.out.%R
, где %R
– это переменная $_SERVER['REQUEST_URI']
(адрес запроса). Другие параметры можно посмотреть в документации XDebug: https://xdebug.org/docs/all_settings#trace_output_name
После перезапуска контейнера видим два файла: один с нашим адресом, а другой со злосчастным favicon_ico.
![Наш профайл нужного адреса и favicon.ico Наш профайл нужного адреса и favicon.ico](https://habrastorage.org/getpro/habr/upload_files/e06/925/c6f/e06925c6ff1385470edebc59ebff31b5.png)
Если мы изучим профайл нашего запроса, то увидим всё то, что нам нужно.
![Профайл нормального запроса Профайл нормального запроса](https://habrastorage.org/getpro/habr/upload_files/7b9/452/a03/7b9452a0382c3d6ba9c9e705146cd5c5.png)
Если Вы исследуете ресурсоёмкие методы, то PHPStorm понадобится какое-то время распарсить профайл, прогресс можно наблюдать в статусбаре.
Это моя первая публикация на Хабре. Если есть вопросы/предложения/критика, пишите в комментариях — обсудим. Телеграм каналы по программированию я не веду, поэтому ссылки не будет. Спасибо за внимание!