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

wp_cron() WP 2.1

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

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

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

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

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

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

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

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

Хуков нет.

Возвращает

Ничего не возвращает.

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

<?php wp_cron() ?>

Примеры

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

// включаем крон задачу, если она еще не включена. 
// Лучше это делать один раз при активации плагина, например
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.');
}

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

#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;
}

Код wp_cron: wp-includes/cron.php VER 4.9.8

<?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;

	if ( false === $crons = _get_cron_array() )
		return;

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

	$schedules = wp_get_schedules();
	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;
			spawn_cron( $gmt_time );
			break 2;
		}
	}
}

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

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

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

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

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

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

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

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

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

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

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

    1
    Ответить2.5 года назад #
  • Добрый день. Пытаюсь использовать 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' );
    

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

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

      1
      Ответить1.4 год назад #
      • Kama7019

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

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

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

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

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

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

            Ответить1.4 год назад #
            • Ерунда какая-то 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

              Ответить1.4 год назад #
              • Kama7019

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

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

                  Ответить1.4 год назад #
                  • Kama7019

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

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

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

              • Kama7019

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

                Ответить1.4 год назад #
  • Рома cайт: bestweb.in.ua

    Привет! В первую очередь огромное спасибо за инфу на сайте! Помоги пожалуйста разобраться, хочу сделать информирование пациентов по расписанию 1 раз в сутки. Для теста поставил пока раз в час. Ничего не происходит. Событие есть, СМСок нет. Даные для отправки проверял, создав шаблон для темы - СМС ходят. По идее не правильно создаю функцию. Если сможешь помоги или подскажи хотя-бы куда копать.

    // включаем крон задачу, если она еще не включена. 
    // Лучше это делать один раз при активации плагина, например
    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() {
    			$time = current_time('Y-m-d');
    			$mod_date = strtotime($time."+ 2 days");
    			$kdata = date("Y-m-d",$mod_date);
    			$args = array(
    					'meta_query' => array(
    					'relation' => 'AND',
    						array ('key'  => 'day' , 'value'  => $kdata),
    						array ('key'  => 'sms_on' , 'value'  => '1')
    						)
    					);
    			$attachments = new WP_Query( $args );
    			while( $attachments->have_posts() ){ $attachments->the_post();    
    				$text_date = get_post_meta( $post->ID, 'zapis', true );
    				$sms_text = "Вы записаны на прием стоматолога $text_date. Ждем Вас!";
    				$phone_number = get_post_meta( $post->ID, 'phone', true );   
    				/*скрипт отправки смс*/
    				$login='****';
    				$pwd='****';
    				$send='****';
    				// Подключаемся к серверу   
    				$client = new SoapClient('http://turbosms.in.ua/api/wsdl.html');   
    				// Данные авторизации   
    				$auth = array( 
    								'login' => $login, 
    								'password' => $pwd 
    							); 
    				// Авторизируемся на сервере   
    				$result = $client->Auth($auth);
    				$sms = array( 
    								'sender' => $send,   
    								'destination' => $phone_number,   
    								'text' => $sms_text   
    							); 
    				// Отправляем СМС
    				$result = $client->SendSMS($sms);    
    			}
    			wp_reset_postdata();
    
    }
    Ответить1.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>';

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

    • @ campusboy3060 cайт: www.youtube.com/c/wpplus

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

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

        • Kama7019

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

  • @ Максим 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 нигде не определена.

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

  • @ lincaseidhe70 cайт: lincaseidhe.ru

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

    • @ lincaseidhe70 cайт: lincaseidhe.ru

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

      1
  • brilik

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

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