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

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

Почему стоит отказаться от WP-Cron для запуска задач

В стандартной реализации WP-Cron не является настоящим системным планировщиком задач. Его запуск зависит от посещений сайта: при отсутствии трафика задачи не запускаются вовремя. Это приводит к задержкам в выполнении важных административных процессов, таких как отправка писем, обновление кэша и прочее.

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

Поэтому для сайтов с критически важными задачами рекомендуется использовать системный cron и отключить WP-Cron.

Отключение WP-Cron и настройка системного cron

Для начала нам нужно отключить встроенный WP-Cron. Для этого в корне WordPress, в файле wp-config.php добавьте следующую строку:

define('DISABLE_WP_CRON', true);

Далее, на сервере нужно создать системное задание cron, которое будет вызывать скрипт запуска задач WordPress с нужным интервалом (например, раз в 5 минут).

Команда для cron может выглядеть так:

*/5 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

Замените https://example.com на URL вашего сайта. Если wget недоступен, можно использовать curl:

*/5 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

Такой подход обеспечит регулярный и своевременный запуск задач без зависимости от посещаемости сайта.

Реализация отложенного запуска задач через пользовательский механизм

Иногда необходимо запускать кастомные задачи с более гибкими условиями и контролем. Ниже мы рассмотрим пример реализации собственного отложенного планировщика задач в WordPress без использования WP-Cron.

Создание таблицы для хранения задач

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

function wpteam_create_task_table() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'wpteam_tasks';
    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE IF NOT EXISTS $table_name (
        id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
        hook VARCHAR(191) NOT NULL,
        args TEXT,
        run_at DATETIME NOT NULL,
        status ENUM('pending', 'running', 'done', 'failed') NOT NULL DEFAULT 'pending',
        PRIMARY KEY  (id),
        INDEX run_at_idx (run_at),
        INDEX status_idx (status)
    ) $charset_collate;";

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}
register_activation_hook(__FILE__, 'wpteam_create_task_table');

Этот код создаст таблицу wp_wpteam_tasks (префикс может отличаться), в которой будут храниться задачи с указанием времени запуска и статуса.

Добавление задач в очередь

Создадим функцию для добавления новых задач в нашу таблицу:

function wpteam_schedule_task($hook, $args = array(), $run_at) {
    global $wpdb;
    $table_name = $wpdb->prefix . 'wpteam_tasks';

    $wpdb->insert(
        $table_name,
        array(
            'hook' => $hook,
            'args' => maybe_serialize($args),
            'run_at' => $run_at,
            'status' => 'pending'
        ),
        array('%s', '%s', '%s', '%s')
    );
    return $wpdb->insert_id;
}

Пример использования:

wpteam_schedule_task('wpteam_send_reminder_email', array('user_id' => 123), date('Y-m-d H:i:s', strtotime('+10 minutes')));

Обработка и выполнение задач

Создадим скрипт, который будет запускаться по cron и обрабатывать задачи, у которых время запуска наступило или прошло:

function wpteam_run_scheduled_tasks() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'wpteam_tasks';

    $now = current_time('mysql');

    // Получаем задачи, которые нужно выполнить
    $tasks = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM $table_name WHERE status = %s AND run_at <= %s",
        'pending', $now
    ));

    foreach ($tasks as $task) {
        // Отмечаем задачу как выполняемую
        $wpdb->update($table_name, array('status' => 'running'), array('id' => $task->id), array('%s'), array('%d'));

        $args = maybe_unserialize($task->args);

        // Выполняем задачу, вызывая hook с аргументами
        do_action_ref_array($task->hook, array($args));

        // Обновляем статус задачи
        $wpdb->update($table_name, array('status' => 'done'), array('id' => $task->id), array('%s'), array('%d'));
    }
}

// Для запуска из командной строки или через cron
if (defined('WP_CLI') || (php_sapi_name() === 'cli')) {
    wpteam_run_scheduled_tasks();
}

Пример задачи: отправка напоминания по email

Добавим обработчик для нашего примера с отправкой email:

add_action('wpteam_send_reminder_email', function($args) {
    $user_id = $args['user_id'] ?? 0;
    if (!$user_id) return;

    $user = get_userdata($user_id);
    if (!$user) return;

    $to = $user->user_email;
    $subject = 'Напоминание от WP-Team';
    $message = 'Здравствуйте, это напоминание от вашего сайта.';

    wp_mail($to, $subject, $message);
});

Интеграция с системным cron

Чтобы системный cron запускал наши задачи, создайте отдельный PHP-файл в корне сайта, например run-wpteam-tasks.php:

<?php
require_once __DIR__ . '/wp-load.php';
wpteam_run_scheduled_tasks();

И настройте системный cron на запуск этого файла, например:

*/5 * * * * /usr/bin/php /path/to/site/run-wpteam-tasks.php > /dev/null 2>&1

Преимущества и рекомендации

  • Наш механизм полностью независим от посещаемости сайта, задачи выполняются точно по расписанию.
  • Вы можете создавать задачи с любым набором аргументов и обрабатывать их в своих хуках.
  • Хранение задач в базе позволяет контролировать статус и предотвращать повторное выполнение.
  • Рекомендуется добавлять логирование ошибок выполнения задач и обрабатывать исключения.
  • Для удобства можно расширить функционал, добавив интерфейс управления задачами в админ-панель.

Заключение

Отказ от стандартного WP-Cron в пользу системного cron и собственного механизма отложенного запуска задач значительно повысит надежность и предсказуемость выполнения фоновых процессов на вашем сайте WordPress. Приведенный пример кода можно адаптировать под любые задачи и расширять по мере необходимости.

Для дополнительной оптимизации рекомендуем ознакомиться с плагином Clearfy Pro, который предлагает улучшения производительности и управления задачами в WordPress.

Как использовать хуки (actions и filters) для настройки WordPress
18.11.2025
Оптимизация загрузки изображений в WordPress для ускорения сайта
06.11.2025
Как добавить поле в регистрацию WordPress с применением хуков
19.01.2026
Как создать динамические виджеты в WordPress с использованием REST API
11.01.2026
Автоматизация создания копий безопасности WordPress: практические решения от WP-Team
29.11.2025