WP Cron-在接下来的三个小时内,每隔15分钟在特定时间运行Cron

时间:2018-07-30 作者:Thomas

在WordPress中,我想安排一个事件,它将在特定时间(比如说在下午6点)运行我的函数(hook),然后在15分钟后再次运行(意味着在下午6:15),并在每15分钟后继续运行3个小时(直到晚上9点),然后它就会消失。

// I have the following code which run after every 6 hours
function myprefix_custom_cron_schedule( $schedules ) {
    $schedules[\'every_six_hours\'] = array(
        \'interval\' => 21600, // Every 6 hours
        \'display\'  => __( \'Every 6 hours\' ),
    );
    return $schedules;
}
add_filter( \'cron_schedules\', \'myprefix_custom_cron_schedule\' );

// Schedule an action if it\'s not already scheduled
if ( ! wp_next_scheduled( \'myprefix_cron_hook\' ) ) {
    wp_schedule_event( time(), \'every_six_hours\', \'myprefix_cron_hook\' );
}

// Hook into that action that\'ll fire every six hours
add_action( \'myprefix_cron_hook\', \'myprefix_cron_function\' );

// create your function, that runs on cron
function myprefix_cron_function() {
    // your function...
}

2 个回复
最合适的回答,由SO网友:Fayaz 整理而成

设置WordPress Cron事件,假设您想在下午6点启动Cron,并在每15分钟后继续运行Cron,直到晚上9点(持续3小时)。然后所有cron停止。

Note: 为简化实现,代码中的所有时间条目都被视为GMT/UTC。

为此,您需要安排两个cron事件,其中一个将在下午6点开始,并从下午6点开始每隔15分钟运行一次。另一个是将在晚上9点运行的一次性cron事件。这一个将阻止另一个cron。

插件代码如下所示:

<?php
/*
Plugin Name:  WPSE Custom Cron
Plugin URI:   https://wordpress.stackexchange.com/a/309973/110572
Description:  Custom Cron Plugin
Version:      1.0.0
Author:       Fayaz Ahmed
Author URI:   https://www.fayazmiraz.com/
*/

add_action( \'wpse_custom_cron_event\',        \'wpse_custom_cron\' );
add_action( \'wpse_custom_cron_event_stop\',   \'wpse_custom_cron_stop\' );

function wpse_custom_cron() {
    // Your Custom Cron CODE HERE
}

function wpse_custom_cron_start() {
    // Calculate the start time: e.g. whenever the next 6:00PM (UTC) is.
    $cron_start_time = strtotime( "today 6:00pm" );
    // If 6PM has already passed today, set it to 6PM next day
    if( $cron_start_time < time() ) {
        $cron_start_time = $cron_start_time + 24 * HOUR_IN_SECONDS;
    }

    if ( ! wp_next_scheduled( \'wpse_custom_cron_event\' ) ) {
        wp_schedule_event( $cron_start_time, \'fifteen_minutes\', \'wpse_custom_cron_event\' );
    }

    if ( ! wp_next_scheduled( \'wpse_custom_cron_event_stop\' ) ) {
        // this 1 time cron will stop the original cron \'wpse_custom_cron_event\' after 3 hours of starting 
        $cron_stop_time = $cron_start_time + 3 * HOUR_IN_SECONDS;
        wp_schedule_single_event( $cron_stop_time, \'wpse_custom_cron_event_stop\' );
    }
}

function wpse_custom_cron_stop() {
    // removing all possible custom cron events named \'wpse_custom_cron_event\'
    while( false !== wp_unschedule_event( wp_next_scheduled( \'wpse_custom_cron_event\' ), \'wpse_custom_cron_event\' ) ) {}
}

// Add a 15 minutes custom cron schedule
add_filter( \'cron_schedules\', \'wpse_custom_cron_schedule\' );
function wpse_custom_cron_schedule( $schedules ) {
    $schedules[\'fifteen_minutes\'] = array(
        \'interval\' => 15 * 60,
        \'display\'  => esc_html__( \'Every Fifteen Minutes\' ),
    );
    return $schedules;
}

// schedule the cron event on plugin activation
register_activation_hook( __FILE__, \'wpse_custom_cron_plugin_activation\' );
function wpse_custom_cron_plugin_activation() {
    wpse_custom_cron_start();
}
// remove the cron event on plugin deactivation
register_deactivation_hook( __FILE__, \'wpse_custom_cron_plugin_deactivation\' );
function wpse_custom_cron_plugin_deactivation() {
    wpse_custom_cron_stop();

    // in case the stop event didn\'t run yet
    while( false !== wp_unschedule_event( wp_next_scheduled( \'wpse_custom_cron_event_stop\' ), \'wpse_custom_cron_event_stop\' ) ) {}
}
此示例插件将在激活插件时启动cron,但如果需要,您也可以使用wpse_custom_cron_start() 作用

此外,如果您想每天下午6点运行同一个cron(而不仅仅是激活后的一次),那么只需更改wp_schedule_single_event 请来wpse_custom_cron_start() 功能到:

wp_schedule_event( $cron_stop_time, \'daily\', \'wpse_custom_cron_event_stop\' );

Note: Event/Cron created with arguments

如果使用参数创建事件/cron,you must also stop the event with the exact same argument.

例如,如果您创建了这样的事件(在wpse_custom_cron_start() 上述代码的功能):

....
wp_schedule_event( $cron_start_time, \'fifteen_minutes\', \'wpse_custom_cron_event\', $args1 );
....
wp_schedule_single_event( $cron_stop_time, \'wpse_custom_cron_event_stop\', $args2 );
然后,在停止事件时,还必须在中使用完全相同的参数wp_next_scheduled() 函数调用。因此,停止代码将变为:

....
while( false !== wp_unschedule_event( wp_next_scheduled( \'wpse_custom_cron_event\', $args1 ), \'wpse_custom_cron_event\' ) ) {}
....
while( false !== wp_unschedule_event( wp_next_scheduled( \'wpse_custom_cron_event_stop\', $args2 ), \'wpse_custom_cron_event_stop\' ) ) {} 
再一次,记住,它必须是exact same argument, 即使不同的数据类型也无法工作。例如,在以下代码中,$args1$args2NOT 同样,但是$args1$args3 相同:

$args1 = array( \'key\' => 1 );
$args2 = array( \'key\' => \'1\' );
$args3 = array( \'key\' => 1 );
因为\'1\' 是字符串和1 是一个数字。

这很重要,因为,sometimes people save the arguments in database as key value pairs, &;当他们稍后再次使用它时,来自数据库的值对数字参数不起作用,因为从数据库检索时数字会转换为字符串。因此,在将参数传递给wp_next_scheduled() 作用

有关更多信息,请查看文档:

  • wp_schedule_event()
  • wp_unschedule_event()
  • wp_schedule_single_event()
  • wp_next_scheduled()define(\'DISABLE_WP_CRON\', true); 在里面wp-config.php 文件,然后从系统crontab运行cron,如下所述in this post.

    使用外部cron服务:

    如果无法设置crontab,可以使用外部cron服务,如cron-job.org 并相应地设置cron。

    例如,对于上述cron事件,您可以使用如下设置在此处设置单个cron作业:

    cron-job.org settings

    这里,所有Days of Month, Days of Week &;Months 已选择;和Hours 已选择收件人18, 19, 20Minutes 已选择收件人0, 15, 30, 45. 这意味着:每天在0、15、30和45分钟(即间隔15分钟)从下午6点运行cron到晚上9点(GTM根据帐户设置设置为时区)。

    Cron检查+手动Cron:

    您可以使用WP Control 插件。此插件还可用于设置自定义cron事件和间隔。

SO网友:Kaperto

要做到这一点,最好每15分钟启动一次cron,然后测试是该进行治疗还是该等待。

您可以尝试这样的方式:

const ACTIVE_PERIOD = 3 * HOUR_IN_SECONDS;
const WAITING_PERIOD = 6 * HOUR_IN_SECONDS;

const TRANSIENT_STATE = "TestCron__state";
const TRANSIENT_TIMEOUT = "TestCron__timeout";


add_action("TestCron/cron/execution", function () {


    $state = get_transient(TRANSIENT_STATE);

    if (FALSE === $state) {
        set_transient(TRANSIENT_STATE, "waiting");
        set_transient(TRANSIENT_TIMEOUT, time() + WAITING_PERIOD);
    }


    if (get_transient(TRANSIENT_TIMEOUT) < time()) { // state change

        if ("waiting" === get_transient(TRANSIENT_STATE)) {
            set_transient(TRANSIENT_STATE, "active");
            set_transient(TRANSIENT_TIMEOUT, time() + ACTIVE_PERIOD);
        } else {
            set_transient(TRANSIENT_STATE, "waiting");
            set_transient(TRANSIENT_TIMEOUT, time() + WAITING_PERIOD);
        }

    }


    if ("waiting" === get_transient(TRANSIENT_STATE)) {
        // continue to sleep
        return;
    }


    // here actions to do
    do_action("myprefix_cron_hook");



});


add_action("wp_loaded", function () {

    if (!wp_next_scheduled("TestCron/cron/execution")) {
        wp_schedule_event(1, "15_minutes", "TestCron/cron/execution");
    }

});


add_filter("cron_schedules", function ($cron_schedules) {

    $cron_schedules["15_minutes"] = [
        "display" => "15 minutes",
        "interval" => 15 * MINUTE_IN_SECONDS,
    ];

    return $cron_schedules;

});

结束

相关推荐

Wp-cron/wp_Schedule_Event是否适合耗时的操作?

我想安排每天运行的操作。此操作可能需要几秒钟的时间。问题是:WP-Cron是否是执行此类操作的合适机制(例如,与经典的Unix-Cron相比)?我这样问的原因是,据我所知,所有WordPress挂钩都是由HTTP请求触发的,可能来自普通访问者或管理员。如果该操作与触发HTTP请求在同一线程中运行,恐怕后者会受到计划操作的影响。一句话:每天一次,不幸的访问者在访问网站时可能会注意到巨大的延迟。那么我可以在wp_schedule_event? 如果是的话,你能描述一下WordPress是如何解决这个问题的吗?