WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

wp_cron() WP 2.1

Запускает все запланированные Крон события, время которых подошло.

Проверяет существует ли хоть одно задание с подошедшем временем. Если да, то вызывает функцию spawn_cron(), которая в свою очередь создает запрос на файл крона /example.com/wp-cron.php.

При вызове этой функции, будут запущены все действия, которые были запланированы и время их запуска уже наступило.

Подробнее про крон читайте в описании функции wp_schedule_event(), которая создает новое крон-событие. Там куча примеров и по сути все то, что нужно знать о крон в WordPress.

Эту функцию не нужно вызывать отдельно. Она вызывается автоматически на событии init:

if ( ! defined( 'DOING_CRON' ) ) {
	add_action( 'init', 'wp_cron' );
}

Если где-то определена константа DISABLE_WP_CRON, то функция ничего не запустит.

Cron — это название взято из UNIX-подобных операционных систем, где в задачи этого демон-планировщика входит: периодическое выполнение заданий в определённое время.

Подробно о Крон: WP Cron (планировщик) в WordPress

Хуков нет.

Возвращает

int/false.

  • Число — при успешном выполнении — число отработанных событий (0 означает что сейчас нет событий которые нужно выполнить).
  • false — когда не удалось обработать хоть одно событие.

Использование

<?php wp_cron() ?>

Примеры

#1. Пример, отправки сообщения ежечасно на email.

Код можно поместить, например, в файл темы functions.php.

// включаем крон задачу, если она еще не включена. 
// Лучше это делать один раз при активации плагина, например
if ( ! wp_next_scheduled( 'my_task_hook' ) ) {
	wp_schedule_event( time(), 'hourly', 'my_task_hook' );
}

// добавляем крон хук
add_action( 'my_task_hook', 'my_task_function' );
function my_task_function() {
	wp_mail( 'your@email.com', 'Автоматическое письмо', 'Запланированное письмо от WordPress.');
}

#2. Добавление крон задачи и своего интервала

Код нужно добавлять в файл functions.php или плагин.

add_filter( 'cron_schedules', 'mycron_add_schedule' );
add_action( 'init', 'mycron_add_hook' );

## добавляет крон функцию
function mycron_add_hook(){
	if ( ! wp_next_scheduled( 'my_cron_worker_start' ) ) { 
		wp_schedule_event( time(), 'my_cron_worker', 'my_cron_worker_start' ); 
	}
}

## добавляет крон интервал времени
function mycron_add_schedule(){
	$schedules['my_cron_worker'] = array( 'interval' => 60, 'display' => 'My Cron Worker' );
	return $schedules;
}

Список изменений

С версии 2.1.0 Введена.
С версии 5.1.0 Return value added to indicate success or failure.

Код wp cron: wp-includes/cron.php WP 5.2.2

<?php
function wp_cron() {
	// Prevent infinite loops caused by lack of wp-cron.php
	if ( strpos( $_SERVER['REQUEST_URI'], '/wp-cron.php' ) !== false || ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) ) {
		return 0;
	}

	$crons = wp_get_ready_cron_jobs();
	if ( empty( $crons ) ) {
		return 0;
	}

	$gmt_time = microtime( true );
	$keys     = array_keys( $crons );
	if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) {
		return 0;
	}

	$schedules = wp_get_schedules();
	$results   = array();
	foreach ( $crons as $timestamp => $cronhooks ) {
		if ( $timestamp > $gmt_time ) {
			break;
		}
		foreach ( (array) $cronhooks as $hook => $args ) {
			if ( isset( $schedules[ $hook ]['callback'] ) && ! call_user_func( $schedules[ $hook ]['callback'] ) ) {
				continue;
			}
			$results[] = spawn_cron( $gmt_time );
			break 2;
		}
	}

	if ( in_array( false, $results, true ) ) {
		return false;
	}
	return count( $results );
}

Cвязанные функции

Из метки: cron (расписание schedule)

26 комментов
Полезные 1 Вопросы 3 Все
  • bowman

    Можно пояснить. Допустим у меня некоторый код в functions.php с функцией wp_schedule_event (...)
    Выполняться код будет только, eсли вызвать на какой-нибудь странице функцию wp_cron() .
    Все правильно?

    Ответить5.3 лет назад #
    • Kama7533

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

      Если вызвать эту функции, то запуск крона будет инициализирован насильно.

      2
      Ответить4.6 года назад #
  • artem78

    Скажите пожалуйста, как определить, что задача выполняется в данный момент?

    Ответить4.3 года назад #
  • @ Andrey

    Здравствуйте, Тимур! А как быть, если нужно не hourly а раз в 15 минут?
    Спасибо!

    1
    Ответить3.2 года назад #
  • Добрый день. Пытаюсь использовать wp-cron в файле, подключаемом через ajax. Но, к сожалению не работает.
    Если разместить код ниже в function.php, то все работает.

    function do_this_in_an_hour() {
    	wp_mail('my-email@gmail.com','Тема тестового письма','Тестовое сообщение');
    }
    add_action('my_new_event','do_this_in_an_hour' );
    wp_schedule_single_event( time() + 60, 'my_new_event' );
    

    Но, если этот же код разместить в подключаемом файле, то не работает. В чем причина?

    Ответить2 года назад #
    • То есть, задача в список добавляется, но не срабатывает sad

      1
      Ответить2 года назад #
      • Kama7533

        Обрати внимание что wp_schedule_single_event() - это одиночное событие. Вызывать эту функцию, как и функцию wp_schedule_event() нужно всего одни раз! Обычно это делается при активации плагина, а при деактивации эти крон задачи нужно удалять...

        Если задача есть в кроне, но она не срабатывает, значит не подключается хук, почему-то.

        В твоем случае, ты хук врубаешь через АЯКС запрос, но запрос крона это не АЯКС запрос, а обычный запрос и конечно этот хук там тупо не добавляется, поэтому и не работает... Поэтому сам хук нужно вешать в functions.php или в плагин или как-то еще, но не по условию, что выполняется именно какой-то аякс запрос.

        Крон запрос запускается отдельно от текущей инициализации скрипта и в нем отдельно грузится среда ВП и т.д. Текущий запрос только вызывает запрос крона, если время подошло...

        1
        Ответить2 года назад #
        • Получается, я не смогу навешать, например, на клик пользователем по кнопке, wp_schedule_single_event() ? Если так, то может есть какие-то обходные пути?

          Ответить2 года назад #
          • В общем, хук добавил в function.php А в файл подключаемый через ajax добавил wp_schedule_single_event. Событие происходит, но несколько раз. А именно по числу посещений сайта с момента запуска запланированной задачи до её выполнения gamer2

            Ответить2 года назад #
            • Ерунда какая-то sad
              перенес wp_schedule_single_event в function.php, задал условие:

              $per = $_POST['per'];
              
              if ( isset($per) ){
              
              	// Создаем массив
              	$post_data = array(
              		'post_title'    => 'Заголовок',
              		'post_content'  => 'Текст',
              		'post_status'   => 'publish',
              		'post_author'   => 999999,
              		'post_type'     => 'copy',
              	);
              	$post_id = wp_insert_post( wp_slash($post_data) );
              
              	function do_this_in_an_hour() {
              		wp_mail('email@gmail.com', 'Тема тестового письма', 'Тестовое сообщение');
              	}
              	add_action('my_new_event', 'do_this_in_an_hour' );
              	wp_schedule_single_event( time() + 30, 'my_new_event' );
              
              }

              Запись появляется, а событие не появляется sad

              Ответить2 года назад #
              • Kama7533

                Чет ты мутишь... Что нужно-то вообще?

                Ответить2 года назад #
                • Создать разовое событие при клике на кнопку пользователем.

                  Ответить2 года назад #
                  • Kama7533

                    А сразу при клике сделать что нужно нельзя, обязательно нужно отложить? Притом как я вижу по коду ты отклыдываешь на 30 секунд. В чем смысл?

                    Ответить2 года назад #
                    • Да, необходимо отложенное действие, так как сервис с которым будет взаимодействовать скрипт выдает результат не сразу, а через время.
                      Суть такая: Пользователь отправляет запрос. Сторонний сервис обрабатывает, а результат приходит только через 15 минут.

                      А 30 секунд - это тестирование. Не могу же я ждать по пол часа

              • Kama7533

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

                Ответить2 года назад #
  • Данную функцию можно использовать при парсинге? Вот к примеру вывожу рейтинг из кинопоиска вот таким скриптом

    $xml = simplexml_load_file('http://rating.kinopoisk.ru/' . 623250 . '.xml');
    if ($xml->imdb_rating != false) {
    	$imdb_rating = $xml->imdb_rating; //рейтинг
    	$num_vote_imdb = $xml->imdb_rating[0]->attributes(); //голоса 
    }
    else{$imdb_rating = '0';}
    echo '<div class="kp-im">
    <div class="kp">
    <span class="kp-rt">'.$xml->kp_rating.'</span>
    <span class="kp-v">'.$xml->kp_rating["num_vote"].'</span>
    </div>
    <div class="im">
    <span class="im-rt">'.$imdb_rating.'</span>
    <span class="im-v">'.$num_vote_imdb.'</span>
    </div>
    </div>';

    Как сделать, чтобы этот скрипт не парсил при каждом обновлении страницы, а к примеру делал это раз в сутки?

    Ответить1.3 года назад #
    • @ campusboy3409 cайт: www.youtube.com/c/wpplus

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

      Ответить1.3 года назад #
      • Фильм это пост. Сохранять данные в метаполя, это слишком сложно, они должны регулярно обновляться и это будет слишком сложно реализовать. Мне бы хотелось создать некую обложку, которая будет парсить раз в сутки.Или данную функцию можно использовать в связке только с метаполями?

        Ответить1.3 года назад #
        • Kama7533

          Ну вот ты выпарсил данные для фильма и сохранить то их куда-то надо пока еще раз не выпарсишь... Лучше всего тут сохранить в метаполе... Крон и метаполя никак не связаны - Дима тебе просто логику рассказал...

          Ответить1.2 года назад #
  • @ Максим cайт: lifecrypt.ru

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

    // регистрируем пятиминутный интервал
    add_filter( 'cron_schedules', 'cron_add_five_min' );
    function cron_add_five_min( $schedules ) {
    	$schedules['five_min'] = array(
    		'interval' => 60*5,
    		'display' => 'Раз в 5 минут'
    	);
    	return $schedules;
    }
    
    // регистрируем событие
    add_action('wp', 'my_activation');
    function my_activation() {
    	if ( ! wp_next_scheduled( 'my_five_min_event' ) ) {
    		wp_schedule_event( time(), 'five_min', 'my_five_min_event');
    	}
    }
    
    // добавляем функцию к указанному хуку
    add_action('my_five_min_event', 'do_every_five_min');
    function do_every_five_min() {
    
    	//Парсинг данных с coinmarketcap в нашу таблицу
    	global $wpdb;
    	$data = json_decode(file_get_contents('https://api.coinmarketcap.com/v1/ticker/?
    convert=RUR&limit=500'), true);
    	if (!is_array($data)) die('Json convert error');
    	foreach ($data as $value => $key) {
    		$wpdb->replace(
    			$wpdb->get_blog_prefix() . 'coinmarket',
    			array( 
    				'id' => esc_sql($key['rank']),
    				'name' => esc_sql($key['id']), 
    			),
    			array( '%d', '%s')
    		);
    	}
    	echo "Выполнено";
    }

    Таблицу слегка урезал для лучшего восприятия, там примерно 10 столбцов и 500 строк.
    Нюансы:

    • событие будет выполнено если на локальном/глобальном хостинге принудительно зайти на lifecrypt/wp-cron.php или обновить любую стринцу.
    • константа DISABLE_WP_CRON нигде не определена.

    Спасибо за помощь.

    Ответить1.2 года назад #
  • @ lincaseidhe76 cайт: lincaseidhe.ru

    Кама привет! Подскажи если знаешь - в логах некоторых сайтов, сайт дергает крон раз в 10 минут. На некоторых сайтах есть, на некоторых - нет. Что может быть? Внутренние крон-задачи у wordpress есть?

    Ответить1.1 года назад #
    • @ lincaseidhe76 cайт: lincaseidhe.ru

      А ладно, вроде разобрался, из jetpack виджет отображения последних записей дергает крон, хотя он у меня вроде не использовался... Но и вообще, в jetpack очень много крон задач установлено, так что если нет острой необходимости в его использовании - лучше отключить...

      1
      Ответить1.1 года назад #
  • Доброго солнца Вам!
    Есть большой поток писем отправленный в разное время. Нужно сделать так, чтобы все эти письма пришли с 6:00 до 7:00. Эта задача с кроном, я правильно пришел? (на хостинг нет доступов, чтобы включить расписание)

    Ответить11 мес назад #
  • @ Вова cайт: korchim.ru

    Привет!

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

    Ответить4 мес назад #
Здравствуйте, !     Войти . Зарегистрироваться