wplearn.ru wordpress WP Learn

Как настроить отложенный запуск задач в WordPress без плагинов

В стандартном функционале 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");
}

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

×
День SEO
Время сделать подарок своему WordPress!
-20% на премиум

шаблоны и плагины

Порадуй свой сайт ⋙