В стандартном функционале WordPress есть встроенная система планировщика задач — WP-Cron, которая позволяет запускать определённые действия в будущем или периодически. Но у WP-Cron есть свои ограничения: задачи запускаются только при обращении к сайту, что может приводить к задержкам или пропускам. В этой статье мы рассмотрим, как настроить отложенный запуск задач и периодические события в WordPress без использования плагинов, а также как оптимизировать работу планировщика.
Что такое WP-Cron и почему его стоит настраивать
WP-Cron — это имитация системного cron, реализованная на PHP в WordPress. Она запускает задачи при загрузке страниц, проверяя, не настало ли время для выполнения запланированных событий. Из-за этого система не подходит для сайтов с низким трафиком или с задачами, требующими точного времени выполнения.
Для решения этих проблем можно:
- Отключить WP-Cron и настроить системный cron на сервере для вызова wp-cron.php по расписанию.
- Использовать кастомные функции для отложенного запуска задач.
- Реализовать управление задачами через пользовательские хуки и фильтры.
Это позволит повысить надёжность и точность работы фоновых процессов на сайте.
Как отключить WP-Cron и настроить системный cron
Для начала отключим автоматический запуск WP-Cron при загрузке страниц, добавив в wp-config.php следующую строку:
define('DISABLE_WP_CRON', true);
Далее настроим системный cron на сервере, чтобы он вызывал скрипт wp-cron.php с определённым интервалом. Например, для запуска каждую минуту добавьте в crontab:
* * * * * wget -q -O - https://ваш-сайт.ru/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Или, если доступ к wget отсутствует, используйте curl:
* * * * * curl --silent https://ваш-сайт.ru/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Этот подход позволяет запускать задачи в нужное время независимо от посещений сайта.
Создание отложенной задачи с помощью WP-Cron API
Рассмотрим пример, как создать простую отложенную задачу, которая выполнится через 10 минут после вызова.
Сначала регистрируем событие и создаём хук для выполнения функции:
function wplearn_schedule_my_task() {
if (!wp_next_scheduled('wplearn_my_custom_event')) {
wp_schedule_single_event(time() + 600, 'wplearn_my_custom_event');
}
}
add_action('init', 'wplearn_schedule_my_task');
add_action('wplearn_my_custom_event', 'wplearn_execute_my_task');
function wplearn_execute_my_task() {
// Здесь ваш код задачи
error_log('Отложенная задача выполнена: ' . current_time('mysql'));
}
В этом примере при инициализации WordPress проверяется, не запланировано ли событие wplearn_my_custom_event. Если нет, то создаётся однократное событие через 10 минут. Когда наступит время, WordPress вызовет функцию wplearn_execute_my_task, где можно разместить нужный код.
Создание периодических задач
Для повторяющихся задач нужно добавить собственный интервал, если стандартные не подходят. Например, создадим интервал в 15 минут:
function wplearn_custom_cron_schedules($schedules) {
if (!isset($schedules['every_fifteen_minutes'])) {
$schedules['every_fifteen_minutes'] = array(
'interval' => 900,
'display' => __('Каждые 15 минут')
);
}
return $schedules;
}
add_filter('cron_schedules', 'wplearn_custom_cron_schedules');
Теперь создадим периодическое событие с этим интервалом:
function wplearn_schedule_recurring_task() {
if (!wp_next_scheduled('wplearn_recurring_event')) {
wp_schedule_event(time(), 'every_fifteen_minutes', 'wplearn_recurring_event');
}
}
add_action('wp', 'wplearn_schedule_recurring_task');
add_action('wplearn_recurring_event', 'wplearn_execute_recurring_task');
function wplearn_execute_recurring_task() {
// Код для периодической задачи
error_log('Периодическая задача запущена: ' . current_time('mysql'));
}
Этот код создаст задачу, которая будет срабатывать каждые 15 минут.
Как отлаживать и контролировать задачи WP-Cron
Для удобства отладки можно использовать плагин WP Crontrol. Он отображает все запланированные задачи, позволяет запускать их вручную и удалять.
Если вы не хотите использовать плагины, можно вывести список задач программно, например:
function wplearn_show_scheduled_events() {
$cron = _get_cron_array();
if (empty($cron)) {
echo 'Задачи не запланированы.';
return;
}
foreach ($cron as $timestamp => $events) {
foreach ($events as $hook => $details) {
foreach ($details as $sig => $data) {
echo 'Хук: ' . esc_html($hook) . ', время: ' . date('Y-m-d H:i:s', $timestamp) . "<br>";
}
}
}
}
add_action('admin_notices', 'wplearn_show_scheduled_events');
Этот код выведет на странице админки список запланированных задач.
Оптимизация и рекомендации по использованию WP-Cron
Чтобы избежать проблем с WP-Cron, придерживайтесь следующих рекомендаций:
- Отключайте автоматический запуск WP-Cron и используйте системный cron для вызова
wp-cron.php. - Минимизируйте количество повторяющихся задач и избегайте слишком коротких интервалов.
- Используйте уникальные имена событий и функций, чтобы не было конфликтов.
- Для тяжёлых или длительных задач запускайте их через очередь или внешние сервисы.
- Регулярно проверяйте и удаляйте устаревшие или неиспользуемые задачи.
Пример комплексной задачи: очистка устаревших записей
Допустим, нужно периодически удалять записи кастомного типа 'wplearn_log', старше 30 дней. Вот пример реализации:
function wplearn_schedule_cleanup_task() {
if (!wp_next_scheduled('wplearn_cleanup_old_logs')) {
wp_schedule_event(time(), 'daily', 'wplearn_cleanup_old_logs');
}
}
add_action('wp', 'wplearn_schedule_cleanup_task');
add_action('wplearn_cleanup_old_logs', 'wplearn_execute_cleanup_task');
function wplearn_execute_cleanup_task() {
global $wpdb;
$date_threshold = date('Y-m-d H:i:s', strtotime('-30 days'));
$table = $wpdb->prefix . 'posts';
$query = $wpdb->prepare(
"DELETE FROM $table WHERE post_type = %s AND post_date < %s",
'wplearn_log',
$date_threshold
);
$deleted = $wpdb->query($query);
error_log("Удалено $deleted старых записей типа wplearn_log");
}
Этот код создаёт ежедневное событие, которое очищает базу от устаревших записей, что помогает держать базу в порядке и улучшать производительность.