Содержание статьи
Отключите псевдокрон в wp-config.php
– иначе никакой стабильности не будет:
define(\'DISABLE_WP_CRON\', true);
Браузерные вызовы крон-хука работают только при внешнем трафике. Никаких запросов – никакого запуска. На малонагруженных сайтах это провал. На высоконагруженных – избыточные вызовы. Оба варианта – компромисс. Хочешь точности? Настраивай системный крон.
Пример системного задания в crontab -e
для вызова через cURL:
*/5 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
Но это лишь внешняя обертка. Основной механизм – хуки: wp_schedule_event
, wp_schedule_single_event
, wp_clear_scheduled_hook
. Порядок регистрации событий критичен. Неиспользуемые хуки не чистятся автоматически. Каждый лишний – мусор в базе. А мусор – это тормоза.
Пример периодического события:
if ( ! wp_next_scheduled( \'my_custom_event\' ) ) {
wp_schedule_event( time(), \'hourly\', \'my_custom_event\' );
}
add_action( \'my_custom_event\', \'my_custom_function\' );
function my_custom_function() {
// код задачи
}
Регистрируйте события при активации плагина. Удаляйте при деактивации. Не оставляйте висячие события – это ловушка.
Внимание! Событие не запустится, если его хук не привязан к действию через
add_action
. Без этого крон просто молчит.
Тонкость: при каждом запуске wp-cron.php
WordPress перебирает список задач. Один запрос – один запуск. Параллельность отсутствует. Очередь не масштабируется. Не рассчитывайте на миллисекундную точность.
Есть кастомные интервалы? Добавляйте через фильтр cron_schedules
. Только не забывайте возвращать массив – иначе сломаете штатные интервалы.
Пример:
add_filter( \'cron_schedules\', \'add_five_min_interval\' );
function add_five_min_interval( $schedules ) {
$schedules[\'five_minutes\'] = [
\'interval\' => 300,
\'display\' => \'Каждые 5 минут\'
];
return $schedules;
}
Важно помнить: Даже одно забытое событие может вызвать сотни ненужных обращений к базе. Следите за чистотой. Проверяйте очередь.
Проверка и отладка: функции wp_get_scheduled_event
, wp_next_scheduled
, wp_unschedule_event
. Консольные команды WP-CLI – мастхэв для продвинутой отладки.
И не используйте wp_schedule_event внутри хуков, которые сами инициируются кроном. Это прямой путь к бесконечной рекурсии. Будет больно. Больно и долго.
Крон в ядре – не задача, а механизм. И этот механизм нужно приручить. Иначе он приручит вас.
Настройка пользовательского события WP-Cron через functions.php
Прямо в functions.php темы добавьте хук регистрации пользовательского события:
if ( ! wp_next_scheduled( \'my_custom_event_hook\' ) ) {
wp_schedule_event( time(), \'hourly\', \'my_custom_event_hook\' );
}
Хук wp_next_scheduled
предотвращает дубли. Без него – каждый раз при загрузке сайта будет добавляться новая задача. Бессмысленно. И вредно.
Далее определите действие, которое нужно выполнять:
add_action( \'my_custom_event_hook\', \'my_custom_event_function\' );
function my_custom_event_function() {
// Пример: очистка пользовательских мета
global $wpdb;
$wpdb->query( \"DELETE FROM $wpdb->usermeta WHERE meta_key = \'_temp_flag\'\" );
}
Всё. С этого момента WordPress будет запускать ваш скрипт каждый час. Но только если кто-то зайдет на сайт. Никто не зашел – крон не сработал. Это реальность WordPress. Не забывайте.
Важно: если сайт на слабом хостинге – избегайте частого расписания. Иначе получите нагрузку и жалобы от провайдера.
Расширить список интервалов можно вручную:
add_filter( \'cron_schedules\', \'add_custom_cron_interval\' );
function add_custom_cron_interval( $schedules ) {
$schedules[\'every_five_minutes\'] = array(
\'interval\' => 300,
\'display\' => \'Каждые 5 минут\'
);
return $schedules;
}
Теперь можно заменить \'hourly\'
на \'every_five_minutes\'
в wp_schedule_event
. Да, так просто.
Внимание! Изменения в functions.php вступают в силу только при первой загрузке страницы после их внесения. Если вы удалили
wp_schedule_event
, старая задача останется активной!
Удаление события? Без wp_clear_scheduled_hook
– никак:
register_deactivation_hook( __FILE__, \'remove_my_cron_event\' );
function remove_my_cron_event() {
wp_clear_scheduled_hook( \'my_custom_event_hook\' );
}
Иначе задача продолжит жить в тени, как зомби. Без тела, но с последствиями.
Только четкость. Только конкретика. Крон – не игрушка, а точный механизм.
Диагностика и устранение проблем с выполнением WP-Cron задач
Начни с проверки: работает ли механизм вызова. Перейди по адресу https://example.com/wp-cron.php?doing_wp_cron
. Если ответ пустой или выдается ошибка – проблема уже здесь. Проверь, не отключен ли вызов событий в wp-config.php
:
define(\'DISABLE_WP_CRON\', true);
Если строка присутствует – запуск требует внешнего триггера, например, через crontab сервера. Без этого система не будет запускать ничего самостоятельно.
Далее – аудит очереди. Добавь в тему отладку:
add_action(\'init\', function() {
if (is_admin()) {
$crons = _get_cron_array();
echo \'<pre>\'; print_r($crons); echo \'</pre>\';
}
});
Проверь наличие задач с устаревшими timestamp. Если есть записи с прошедшими датами, но они не выполняются – что-то блокирует обработку.
Возможно, есть конфликт. Плагины могут вмешиваться в работу через remove_action()
или фильтры. Подозреваешь конкретный – отключи и проверь повторно.
Внимание! Частая причина – кэширование. Если фронтенд не запускает хук
init
, очередь не обрабатывается вообще.
В этом случае можно форсировать запуск через внешний скрипт, например, настроив вызов в Linux crontab:
*/5 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Проверяй логи сервера. Ошибка 500 при обращении к wp-cron.php
сигнализирует о фатальной проблеме в одном из плагинов или тем. Включи режим отладки в wp-config.php
:
define(\'WP_DEBUG\', true);
define(\'WP_DEBUG_LOG\', true);
После этого смотри wp-content/debug.log
. Ошибки внутри задач – норма. Их нужно отлавливать вручную. Нет логов – значит, задача даже не стартовала.
Важно помнить: если сайт сильно посещаем, очередь может запускаться слишком часто, вызывая нагрузку на сервер. Отключи внутренний механизм и замени на системный планировщик.
Нужна уверенность? Установи плагин WP Crontrol
. Он показывает, какие события запланированы, их параметры, возможность ручного запуска. Но не всегда корректно работает с мультисайтом или нестандартными хостингами.
Случайный запуск? Некоторые задачи не фильтруют входные данные и могут запускаться при каждом хите. Это ошибка логики. Проверь условия внутри функций, особенно если работаешь с wp_schedule_event
.
Если очередь забита – чисти вручную. Через wp_options
таблицу, поле cron
, но только если знаешь, что делаешь. Одна ошибка – и все события пропадут.
Отключение встроенного WP-Cron и настройка через системный cron-сервис
Сначала – выключить псевдокрон в конфигурации:
define(\'DISABLE_WP_CRON\', true);
Вставляется в wp-config.php
до строки /* That\'s all, stop editing! */
. Не позже. Не позже, слышите?
Далее – системный планировщик. Только реальный, только crontab. Введите команду:
crontab -e
И добавьте строку:
*/5 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Интервал – каждые 5 минут. Меньше – бессмысленно. Больше – тормоза. Указывайте свой реальный адрес сайта, без кэша. Никаких редиректов. Переадресации ломают всё.
Внимание! Не указывайте домен с www, если сайт работает без него. Ошибка – и задачи не запускаются вовсе.
Хостинг shared? Проверяйте, поддерживается ли crontab. Многие панели (cPanel, ISPmanager) дают визуальный интерфейс. Но это не повод расслабляться.
Важно помнить:
Если сайт за Cloudflare, убедитесь, что он не блокирует вызовы wp-cron.php. В противном случае – никаких событий. Тишина.
Проверка? Открыть https://example.com/wp-cron.php?doing_wp_cron
в браузере. Белый экран – норма. Ошибки – копать логи.
Альтернатива: curl:
*/5 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron >/dev/null
Стабильнее. Особенно на серверах без wget. Иногда единственный выход.
Не забудьте: права доступа, защита .htaccess, базовая аутентификация – всё это может мешать вызову скрипта. Проверяйте руками. Доверяй, но перепроверяй. Каждую строку.