WP Cron Не Выполняется По Истечении Времени


Цель

Я хочу использовать wp_schedule_single_event( ) для выполнения одного события, которое отправляет мне электронное письмо через 8 минут после того, как пользователь отправит форму.

Проблема

Следующий код находится в моем functions.php:

function nkapi_send_to_system( $args ) {
  wp_mail( 'xxx', 'xxx', $args );
}

add_action( 'nkapi_send', 'nkapi_send_to_system' );

function schedule_event( $id ) {
  wp_schedule_single_event( current_time( 'timestamp' ) + 480, 'nkapi_send', array( $id ) );
}

И следующий код используется для вызова schedule-event:

schedule_event( $_SESSION['insert_id'] ); // the $_SESSION var contains an INT

После ожидания более 8 минут в моем почтовом ящике не было электронного письма.

Что я пробовал

С помощью плагина Управление ядром можно увидеть, что запланированы задания cron.

Core Control screen

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

Но почему хроны не выполняются, когда я захожу на свой сайт через 8 минут. Что, возможно, не так с этим кодом? Я должен сказать, что это мой первый раз, когда я использую WP Cron.

Я пробовал больше

После комментария ванкодера id решил проверить, соответствует ли код работает, если я помещу следующий код непосредственно в functions.php:

function schedule_event( $id ) {
  wp_schedule_single_event( time(), 'nkapi_send', array( $id ) );
}

if ( isset( $_SESSION['insert_id'] ) ) {
  if ( ! array_key_exists( 'insert_scheduled', $_SESSION ) || $_SESSION['insert_scheduled'] != $_SESSION['insert_id'] ) {
    schedule_event( $_SESSION['insert_id'] );
    $_SESSION['insert_scheduled'] = $_SESSION['insert_id'];
  }
}

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

Author: Michael Ecklund, 2013-03-27

6 answers

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

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

Затем вам придется вручную создать задание cron (используя cpanel, если вы находитесь на общем хостинге среде или с терминала, если это VPS/выделенный сервер), который будет посещать эту страницу каждые несколько минут.

Надеюсь, это поможет!

 8
Author: WPMU-DEV Ari, 2013-04-06 01:44:56

Во-первых, определите свои пользовательские расписания заданий cron.

add_filter('cron_schedules', array($this, 'cron_schedules'));

public function cron_schedules($schedules){
    $prefix = 'cron_';// Avoid conflict with other crons. Example Reference: cron_30_mins
    $schedule_options = array(
        '30_mins' => array(
            'display' => '30 Minutes',
            'interval' => '1800'
        ),
        '1_hours' => array(
            'display' => 'Hour',
            'interval' => '3600'
        ),
        '2_hours' => array(
            'display' => '2 Hours',
            'interval' => '7200'
        )
    );
    /* Add each custom schedule into the cron job system. */
    foreach($schedule_options as $schedule_key => $schedule){
        $schedules[$prefix.$schedule_key] = array(
            'interval' => $schedule['interval'],
            'display' => __('Every '.$schedule['display'])
        );
     }
     return $schedules;
}

Вам нужно решить, где и когда на самом деле запланировать мероприятие.

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

$schedule = $this->schedule_task(array(
    'timestamp' => current_time('timestamp'), // Determine when to schedule the task.
    'recurrence' => 'cron_30_mins',// Pick one of the schedules set earlier.
    'hook' => 'custom_imap_import'// Set the name of your cron task.
));

Вот код, который фактически планирует событие:

private function schedule_task($task){
    /* Must have task information. */
    if(!$task){
        return false;
    }
    /* Set list of required task keys. */
    $required_keys = array(
        'timestamp',
        'recurrence',
        'hook'
    );
    /* Verify the necessary task information exists. */
    $missing_keys = array();
    foreach($required_keys as $key){
        if(!array_key_exists($key, $task)){
            $missing_keys[] = $key;
        }
    }
    /* Check for missing keys. */
    if(!empty($missing_keys)){
        return false;
    }
    /* Task must not already be scheduled. */
    if(wp_next_scheduled($task['hook'])){
        wp_clear_scheduled_hook($task['hook']);
    }
    /* Schedule the task to run. */
    wp_schedule_event($task['timestamp'], $task['recurrence'], $task['hook']);
    return true;
}

Теперь все, что вам нужно сделать, это позвонить по имени вашей пользовательской задачи cron. В этом примере имя задачи cron custom_imap_import.

add_action('custom_imap_import', array($this, 'do_imap_import'));

public function do_imap_import(){
    // .... Do stuff when cron is fired ....
}

Итак, в этом примере $this->do_imap_import(); вызывается каждые 30 минут (при условии, что у вас достаточно трафика на ваш сайт).


Примечания

Требуется посещение страницы, чтобы ваш cron срабатывал в нужное время.

Пример: Если вы запланировали задачу с интервалом в 30 минут, но никто не посещает ваш сайт в течение 4 часов, ваша работа cron не будет уволена, пока этот посетитель не зайдет на ваш сайт 4 часа спустя. Если вы действительно действительно нуждаетесь в своем задание запускается каждые 30 минут, затем рекомендуется настроить законное задание cron через вашего провайдера веб-хостинга, чтобы посещать ваш веб-сайт с требуемыми интервалами.

Задания cron WordPress не замедляют работу вашего сайта!

Возможно, вы думаете, что, если выполнение cron-скрипта займет много времени, посетителям придется ждать, пока скрипт будет выполнен. Нет! Как это может быть возможно? Если вы посмотрите на файл wp-cron.php, вы найдете строка

ignore_user_abort(true);

Это конфигурация php.ini, которая устанавливает, что если вы прекратите загрузку сайта/скрипта, скрипт не прекратит выполнение.

Если вы посмотрите на файл wp-includes/cron.php, вы найдете такую строку:

wp_remote_post( $cron_url, 
array('timeout' => 0.01,
 'blocking' => false, 
 'sslverify' => apply_filters('https_local_ssl_verify', true)) );

Это означает, что WordPress будет ждать всего 0,01 секунды для запуска выполнения, затем оно будет прервано, но, как вы установили ignore_user_abort в true, скрипт будет выполняться. Эта функциональность является огромным преимуществом для выполнения больших скриптов в WordPress cron работа.

Функции, доступные для помощи:

 16
Author: Michael Ecklund, 2013-04-04 14:29:46

WordPress Cron позволяет вам планировать задачи, но они будут выполняться только в том случае, если на сайт будет сделан запрос. Для каждого запроса, который получает WordPress, он проверяет, есть ли задания cron для обработки, и если да, то асинхронно отправляет запрос /wp-cron.php?doing_wp_cron для обработки задания. Если запланированный запуск задания проходит без запроса, то процесс cron не будет запущен.

Поскольку вы можете просматривать и выполнять запланированные задания, вполне возможно, что запросов нет это запускает задание cron, особенно если вы используете плагин кэширования. Лучший вариант для переноса этого в более регулярное расписание - отключить проверку по умолчанию в WordPress и использовать crontab.

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

// Disable default check for WordPress cron jobs on page loads
define( 'DISABLE_WP_CRON', true );

Затем вы создаете задачу для извлечения страницы wp-cron.php раз в минуту для обработки любых заданий на серверной части, в командной строке введите crontab -e, а затем добавьте строка, которая выглядит следующим образом:

*/1 * * * * /usr/bin/curl --silent http://example.com/wp-cron.php?doing_wp_cron=$(date +\%s.\%N) >/dev/null 
 4
Author: doublesharp, 2016-09-20 20:21:27

Для любого, кто защищает свой (разрабатываемый) сайт от публичного доступа, аутентификация HTTP может быть причиной того, что WP Cron не работает.

На случай, если это может кому-то помочь, вот мой список того, что я сделал, прежде чем определить и понять требования WP Cron:

  • Я заметил, что события были правильно запланированы и могли быть запущены с помощью WP-CLI.
  • А также заметил, что доступ к /wp-cron.php?выполнение_wp_cron через браузер вызывало выполнение, как предлагается, например, в 13625.
  • Официальная документация была прочитана.
  • Я убедился, что параметр DISABLE_WP_CRON не установлен.
  • И узнал, что ALTERNATE_WP_CRON был успешным, но неудовлетворительным обходным решением.
  • Чтобы исключить ошибки регрессии, я попытался установить пару старых версий wordpress.
  • Все плагины были отключены, а тема переключена на тему по умолчанию, чтобы изолировать проблему.
  • Люди упоминали термин обратные связи , но, не имея связанных с этим ошибок или предупреждений, я счел это неуместным.
  • Наконец, был найден вопрос с ответом, фактически объясняющим, как отлаживать cron.
  • После присоединения Xdebug к wp_cron() я действительно мог видеть, что выполнение закончилось в wp_remote_post(), что явно не удалось.

Зная, что искать, я нашел эту отличную статью о причинах проблем WP Cron Джеффа Старра. В конце он ссылается на свой плагин wp-cron-http-auth.

 3
Author: sampi, 2020-06-17 07:54:58

Убедитесь, что параметр DISABLE_WP_CRON не задан в вашей конфигурации.

В противном случае попробуйте отключить все плагины (кроме core control - хотя я бы использовал wp-crontrol) и посмотрите, работают ли ваши основные задания. Если они это делают, вы где-то сталкиваетесь с помехами плагина.

Аналогично, попробуйте переключиться на стандартную тему для двадцатилетних.

Если ничего из этого не имеет значения, скорее всего, это проблема с хостингом.

 0
Author: vancoder, 2013-04-04 17:19:23

Проверьте любой плагин, который скрывает Wordpress.

Как узнать, в этом ли проблема?

  1. Перейдите к http(ам)://yoursite.com/wp-cron.php Вы должны увидеть пустую страницу. Совершенно пустой.
  2. Кроме того, вы должны видеть в диспетчере заданий cron время в разделе "Следующее выполнение".: Cron job scheduled - if wp-cron.php works properly (не только текст "В очереди", но и заданное время - для некоторых записей "В очереди" иногда нормально, но если это единственное, что вы видите - > ваш cron не работа.)

+1. Не верьте никаким плагинам, которые "проверяют, работает ли cron" - например, плагин проверки статуса WP Cron показал, что cron работает. Но на самом деле этого не произошло. Whatever it shows - believe your eyes and not this plugin!

Вывод: Если это ошибка 404 - отключите а) не только плагины кэширования, как предлагают другие б), но и любые плагины, которые скрывают Wordpress.

 0
Author: Peter Cz, 2019-04-15 21:45:30