Превращаем отладку в WordPress в приятное и увлекательное занятие

Нам часто приходится заниматься отладкой в WordPress. Это может быть и на стенде в Docker или сервере разработки и на PROD серверах у заказчиков. И если вы хотя бы раз пытались сделать то же самое, то наверняка знаете, что процесс отладки кода не так прост, как может показаться на первый взгляд.

В этот статье хочу поделиться некоторыми трюками, которые очень упрощают отладку и во время разработки сайта на WordPress и при поддержке сайтов на PROD-серверах.

Основные проблемы при отладке

Важно понимать, что WordPress, как, впрочем, и любая развитая CMS, не представляет собой что-то монолитно законченное, а скорее это агломерат большого числа разнородных кусков кода, к тому же, написанных и созданных разными людьми. Это и ядро WP, и тема, и большое количество плагинов.

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

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

$ cd /var/www/html   # Здесь подставьте свою реальную папку с сайтом
$ tail -f ./wp-content/debug.log | grep "error"

Но у такого подхода есть проблема – вы увидите только первую строчку при возникновении ошибки, а ее бывает недостаточно. Ниже будет показано, как можно увидеть всё.

Стандартный механизм отладки в WordPress

Сначала необходимо рассмотреть стандартный отладочный механизм WordPress, который заключается в том, что WP выводит разные отладочные сообщения в файл лога debug.log, который по умолчанию находится в папке wp-content.

Его расположение и сам вывод отладочных сообщений определяется константой WP_DEBUG_LOG, которая может задаваться (но не задается по умолчанию) в файле wp-config.php. Вообще, рекомендуется ее задать вместе с другими константами отладки примерно вот таким кодом:

define('WP_DEBUG', false);
define('SAVEQUERIES',  WP_DEBUG);
define('WP_DEBUG_LOG', WP_DEBUG); 
define('SCRIPT_DEBUG', WP_DEBUG);
define('WP_DEBUG_DISPLAY', false);
@ini_set('display_errors', 0);

Замените этим фрагментом стандартный блок отладки в wp-config.php после блока комментариев с фразой

* Для разработчиков: Режим отладки WordPress.

Что делает код, приведенный выше? Во-первых, он определяет требуемые константы и сводит их все к значению константы WP_DEBUG. Если она включена (значение true), то все остальные функции отладки тоже  включаются. Во-вторых, этот фрагмент кода принудительно отключает вывод любых ошибок на экран, чтобы не ломать сайт, AJAX и REST API.

Таким образом, теперь включение и выключение отладки производится буквально одной строчкой – установкой WP_DEBUG в положение true/false. Это очень удобно делать с помощью командной строки и wp-cli. И именно так и рекомендуется!

Что такое wp-cli?

wp-cli – это мощнейшее средство для управления сайтом WordPress из командной строки Linux. Процесс установки и команды подробно приведены на сайте https://wp-cli.org/ и настоятельно рекомендуется этим пользоваться.

Чтобы ввести любую команду wp-cli нужно сначала перейти в любую папку (не обязательно рутовую) сайта. Например, как быстро посмотреть список плагинов на вашем сайте в командной строке SSH:

$ cd /var/www/html     # Здесь надо указать правильный путь к своему сайту
$ wp plugin list

Вот результат:

wp-cli вывод списка плагинов

Для работы с отладкой очень удобно использовать команды wp config, например, вывести параметры конфигурации базы данных:

$ wp config list DB

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

Для быстрой модификации используйте команду:

$ wp config set WP_DEBUG true --raw

Это команда установит значение WP_DEBUG в файле wp-config.php.

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

Легко догадаться, что эта команда включит режим отладки на сайте. А выключить его можно с помощью команды:

$ wp config set WP_DEBUG false --raw

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

Отлично! Включив отладку, мы можем посмотреть лог с помощью команды

$ tail -f ./wp-content/debug.log

Предполагается, что вы в рутовой (домашней) папке сайта. Команда tail -f выводит все последние записи в файл лога на экран.

Прекратить ее работу можно с помощью [Ctrl] + [C], а если требуется временно приостановить вывод, например, что-то сделать, а потом вернуться к выводу лога, то нажмите [Ctrl] + [Z], а чтобы вернутся в вывод лога, наберите команду fg.

Команда fg в Linux

Но скорее всего вы увидите большое число разных сообщений, причем подавляющее число будет как раз PHP Notice:

PHP Notice в файле debug.log

Откуда они берутся? Как уже отмечалось выше, WordPress – это большой конгломерат самого разнородного кода, и далеко не факт, что этот фрагменты кода полностью согласованы между собой. Устаревшие плагины, функции в теме могут выполнять ряд действий, которые приводят к появлениям уведомлений и предупреждений в логе, например, вызывать устаревшие функции.

Конечно же, это полезная информация при разработке, но на отладке она сильно мешает, потому что поймать действительно важные сообщения невозможно без фильтрации, например, grep, как было показано выше. Надо бы выключить эти уведомления.

Отключение E_NOTICE в debug.log

Вообще выводом в лог управляет параметр PHP error_reporting (и одноименная функция) в файле php.ini. Однако именно в WordPress просто так этот параметр не изменить. Дело в том, что по каким-то лично мне непонятным причинам разработчики WordPress принудительно устанавливают этот параметр в положение E_ALL, то есть выводить в лог всё, при загрузке ядра WP. И любые модификации в php.ini будут перекрыты этой установкой. Точно также не поможет изменения этого параметра в теме (functions.php), в конфигурации (wp-config.php) или в плагинах. Потому что wp-config.php загружается до ядра, и ядро его изменит, а тема после плагинов и плагины уже успеют насыпать кучу уведомлений в лог.

И здесь нам на помощь приходят так называемые Must Use Plugins – специальный механизм WordPress, который позволяет сделать системный плагин, который будет загружен сразу после ядра и до загрузки основных плагинов. К тому же, такой плагин не отключается и не управляется через админку. Это как раз то, что нам нужно!

Чтобы создать такой плагин достаточно разместить файл кода в папке wp-content/mu-plugins. Создайте ее, если ее нет.

Итак, создаем новый файл set-error-reporting.php в папке wp-content/mu-plugins со следующим содержимым:

<?php
/**
 * Plugin Name:       Set Error reporting
 * Plugin URI:        https://ivannikitin.com/2022/12/16/wordpress-debug-log/
 * Description:       Установка уровня ошибок в WordPress
 * Version:           0.1
 * Requires at least: 5.2
 * Requires PHP:      7.4
 * Author:            Иван Никитин
 * Author URI:        https://ivannikitin.com/team/ivan/
 *
 * Плагин устанавливает правильный уровень ошибок в debug.log
 *
 * Как вариант может быть и таким
 * E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
 */
error_reporting( E_ALL &  ~(
    E_NOTICE
    | E_USER_NOTICE
    | E_DEPRECATED
    | E_USER_DEPRECATED
    | E_WARNING
    | E_CORE_WARNING
    | E_COMPILE_WARNING
));

И, собственно, всё! Включаем отладку и смотрим на вывод в лог:

$ wp config set WP_DEBUG true --raw
$ tail -f ./wp-content/debug.log

В логе только нужные нам данные: ошибки и явные предупреждения! Теперь работать с ним можно очень удобно и легко! Например, можно открыть его в терминале VS Code:

Вывод debug.log в VSCode

Только не забудьте выключить отладку после работы с помощью команды:

$ wp config set WP_DEBUG false --raw

Вывод своих отладочных сообщений в debug.log

Теперь, когда в лог файл у нас выводятся только действительно нужные сообщения, мы можем в него выводить и свои сообщения и любую другую отладочную информацию с помощью стандартной функции PHP error_log(). Единственный момент в ее использовании заключается в том, что аргумент должен быть только строкой, без null или чего-то еще, иначе функция ничего не выведет. Очень удобно использовать var_export(), например, выведем информацию о текущем пользователе:

error_log( var_export( wp_get_current_user(), true ) );

не забудьте в var_export() вторым параметром передать true, иначе она выведет информацию на экран, а не в лог.

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

Выполнение  произвольного кода в командной строке

Ну и еще один трюк здорово упрощает отладку: часто надо быстро проверить работу какой-либо функции WP, вывести переменную и т.п. То есть, выполнить какой-либо фрагмент кода WP и посмотреть результат. Это можно сделать прямо из командной строки с помощью WP-CLI и команды wp eval. Например, выведем текущего пользователя:

$ wp eval "var_dump( wp_get_current_user() );"
var_dump wp_get_current_user()

Проверим отправку почты с сайта:

$ wp eval "wp_mail( 'ivan@nikitin.biz', 'Тестовое письмо', 'Тест' );"
Отправка почты из командной строки
Тестовое письмо в Outlook

Единственный момент: не забывайте в конце кода PHP ставить точку с запятой, без нее не работает, а возвращает ошибку.

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

Добавить комментарий