WP Cron在时间流逝时不执行

时间:2013-03-27 作者:Mike Madern

我想使用的目标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分钟多后,我的收件箱中没有电子邮件。

我用插件尝试的内容Core Control 可以看到安排了哪些cron作业。

Core Control screen

在做了几次修改后,我成功地使它们非常正确,而且更好的是,当我点击“立即运行”时,我实际上在收件箱中收到了一封电子邮件。

但是为什么当我在8分钟后访问我的站点时,cron不执行呢。此代码可能有什么问题?我不得不说,这是我第一次使用WP-Cron。

I tried more

在的评论之后vancoder 如果我将以下代码直接放入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\'];
  }
}
此代码的缺点是,在执行此代码之前,用户必须转到另一个页面。但另一方面,这也不行,所以这不是我的第一个问题。。。

6 个回复
最合适的回答,由SO网友:WPMU-DEV Ari 整理而成

首先,你能确认你没有启用任何缓存插件吗?缓存插件可能会干扰cron作业,因为您的访问者不会获得实时页面,而是页面的缓存版本。

如果启用了缓存插件,则可以选择其中一个页面,在该页面的缓存插件设置中添加一个Exclusion,以便永远不会缓存该页面。

然后,您必须手动创建一个cron作业(如果您在共享托管环境中,则使用cpanel;如果是VPS/专用服务器,则从终端创建),每隔几分钟访问一次该页面。

我希望这有帮助!

SO网友:Michael Ecklund

首先,定义自定义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在正确的时间启动。

Example: 如果您每隔30分钟安排一项任务,但4小时内没有人访问您的站点,则在该访问者4小时后访问您的站点之前,您的cron作业不会被解雇。如果您确实需要每30分钟启动一次任务,建议您通过web托管提供商设置一个合法的cron作业,以便在所需的时间间隔访问您的网站。

WordPress cron jobs don\'t make your website slow!

也许您在想,如果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_aborttrue 将执行脚本。这个功能对于在WordPress cron作业中执行大型脚本来说是一个巨大的优势。

Functions available for aid:

SO网友:doublesharp

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 

SO网友:sampi

对于任何保护其(开发)站点不受公共访问的人来说,HTTP身份验证可能是WP Cron无法运行的原因。

如果它可以帮助任何人,以下是我在确定和理解WP Cron的需求之前所做的事情:

我注意到事件安排正确,可以使用WP-CLI.13625.

  • The official documentation 已读取
  • 我确保未设置DISABLE_WP_CRONALTERNATE_WP_CRON 是一个成功但不令人满意的解决方法loopbacks, 但由于没有相关的错误或警告,我认为这无关紧要a question with an answer actually explaining how to debug cron 已找到Xdebug 对于wp\\u cron(),我确实可以看到执行以wp\\u remote\\u post()结束,这显然失败了great article on causes for WP Cron issues 杰夫·斯塔尔。最后,他链接到wp-cron-http-auth 插件。

  • SO网友:vancoder

    检查配置中是否未设置DISABLE\\u WP\\u CRON。

    如果做不到这一点,请尝试禁用所有插件(核心控制除外,尽管我会使用wp crontrol),看看您的核心作业是否正常工作。如果他们这样做了,那么您在某个地方遇到了插件干扰。

    同样,尝试切换到标准的20多岁主题。

    如果这些都不起作用,那么很可能是托管问题。

    SO网友:Peter Cz

    检查任何隐藏Wordpress的插件。

    如何判断这是否是问题所在?

    导航到http://您的站点。com/wp cron。PHP您应该看到一个空白页。一个完全空的Cron job scheduled - if wp-cron.php works properly(对于某些条目,“In queue”有时不仅可以显示文本“In queue”,还可以显示给定的时间,但如果这是您看到的唯一内容->您的cron不起作用。)+1。不要相信任何“检查cron是否工作”的插件,例如WP cron status checker插件显示cron工作。但事实并非如此。Whatever it shows - believe your eyes and not this plugin!

    结论:如果是404错误,那么关闭a)不仅像其他人建议的那样缓存插件b)而且关闭任何隐藏Wordpress的插件。

    结束

    相关推荐

    预定的帖子和wp-cron-如果太旧了,为什么预定的帖子不发布?

    我注意到wp_schedule_single_event 提及以下内容:-如果计划时间已过,当有人访问您的WordPress站点时,该操作将启动。然而,这似乎不适用于预定的帖子。我注意到,如果wp cron暂时不运行(不确定确切的时间范围),可能会错过一些帖子。然后,帖子的管理面板中会有“Missed Schedule”的标签。我的问题是:-这只是针对预定的帖子还是所有预定的活动?在错过预定post之前,必须运行wp cron的时间范围是什么?该时间段在代码中的何处设置?我似乎在wp cron中找不到它。