Wordpress-如何安排每48小时运行一次功能

时间:2019-02-05 18:29:01

标签: php wordpress loops cron schedule

我在数据库中保存了一系列报价,我希望每48小时从数据库中提取一个随机的报价并显示在我的网站上。

我发现了使用自定义cron计划事件每48小时进行一次调度的代码。但是,我假设我没有正确实现它,因为尽管站点上显示了一个随机报价,但每次刷新页面时(而不是每48小时一次)它都会切换到新的随机报价。

function quote_custom_cron_schedule( $schedules ) {
$schedules['every_two_days'] = array(
    'interval' => 172800, // Every 48 hours
    'display'  => __( 'Every 48 hours' ),
);
return $schedules;
}
add_filter( 'cron_schedules', 'quote_custom_cron_schedule' );

//Schedule an action if it's not already scheduled
if ( ! wp_next_scheduled( 'quote_cron_hook' ) ) {
wp_schedule_event( time(), 'every_two_days', 'quotes_cron_hook' );
}

//Hook into that action that'll fire every 48 hours
 add_action( 'quotes_cron_hook', 'quotes_cron_function' );

//Function that executes via cron
function quotes_cron_function() {
$args = array(
'post_type' => 'quote',
'orderby' => 'rand',
'posts_per_page'=> 1,
);

  $quotes = new WP_Query( $args );
  $quotes_output = '';

  if( $quotes->have_posts() ):
    while ( $quotes->have_posts() ) : $quotes->the_post();
      $quotes_title = get_the_title();
      $quotes_content = get_the_content();
      $quotes_output .= '<div id="quote"><p>&quot;' . $quotes_content . '&quot;</p><p class="quote-name">' . $quotes_title . '</p></div>';
    endwhile;
  else:
      $quotes_output = '';
  endif;

  wp_reset_postdata();
  echo $quotes_output;
}

然后我的header.php文件中包含以下内容:

<?php do_action( 'quotes_cron_hook' ); ?>

这正在执行该功能,但是每次刷新页面时都会执行。我需要函数等待48小时才能再次更改报价。我觉得这里可能缺少一些简单的东西。

2 个答案:

答案 0 :(得分:1)

您的问题很可能是这样:

if ( ! wp_next_scheduled( 'quote_cron_hook' ) ) {
    wp_schedule_event( time(), 'every_two_days', 'quotes_cron_hook' );
}

在您有quote_cron_hookquotes_cron_hook插入的地方,有一个s没有插入的地方。这种不匹配将导致条件永不失败,因为事件被命名为错误,从未计划,并且此条件在每个单个请求上均通过。依次以开始时间wp_schedule_event运行time函数(见下文)。

如果您查看下面的wp_schedule_event链接文档。您拥有time()的第一个参数是

  

$ timestamp (整数)(必需),您第一次希望事件发生。这必须是UNIX时间戳格式。 WP cron使用UTC / GMT时间,而不是本地时间。使用time(),在WordPress中始终为格林尼治标准时间。

请注意以下事项您第一次希望该事件发生,目前time()是正确的,并且由于其名称错误,它会在每次页面加载时执行此操作,然后立即运行

您当然可以将time()设置为其他内容,但这只会掩盖问题。

其他内容

这也可能是错误的。

  wp_schedule_event( time(), 'every_two_days', 'quotes_cron_hook' );

更具体地说,请查看文档

https://codex.wordpress.org/Function_Reference/wp_schedule_event

  

$ recurrence (字符串)(必需)(事件应多久发生一次)。有效值:

     
      
  • 每小时
  •   
  • 每天两次
  •   
  • 每日
  •   
     

默认:无

除非没有记录,否则我看不到every_two_days。老实说,我没有使用过WP调度程序。 Default: None可能是您在此处实际拥有的,因为WP无法识别该值,因此它回落为零。但是我不确定到底是什么。

更多其他内容

正如我在评论中所说(您可以使用,但请记住)

  

wp调度程序只能在发生活动请求时运行,因此wp调度程序只能授予作业在给定时间之前不会运行的权限。没有被授予者将在此之后的特定时间运行,而是在分配的时间之后在下一个请求上运行

将此添加到wp-config.php

 define('DISABLE_WP_CRON', true);

禁用内置的cron / scheduler。然后进入C-Panel或编辑crontab(crontab -e)并添加此cron作业以每分钟(或一些有用的时间间隔)运行

 php -q pathtowp/wp-cron.php

这是什么,它将控制时序的控制从wordpress转移到了“实际的” CRON应用程序(在Linux上)。这样,它就不再依赖页面加载了。

但是,正如我所说的,并且由于这是某人应查看的帖子,因此正常的WP行为可能对您而言完全正常。通常,如果我对调度程序做任何事情,我都只能依靠真正的CRON,这就是我提到它的原因。

希望有帮助!

答案 1 :(得分:0)

我认为您正在以错误的方式思考。您的标题中有do_action( 'quotes_cron_hook' ),该标题将在每次页面加载时触发quotes_cron_hook操作,然后使quotes_cron_function()每次触发时都可以挂接到该操作。这似乎与您报告的行为一致。

问题是,设置WP cron作业不会强制挂钩仅在该特定时间间隔运行。对于您而言,quotes_cron_hook操作会在每次加载页面时触发,但也会每48小时触发一次。

在我看来,您想要的功能是提取“临时”报价,然后每48小时更改一次。为此,您需要类似的东西:

if ( ! wp_next_scheduled( 'change_quote_hook' ) ) {
    wp_schedule_event( time(), 'every_two_days', 'change_quote_hook' );
}

add_action( 'change_quote_hook', 'change_quote_function' );

function change_quote_function() {
      $args = array(
          'post_type' => 'quote',
          'orderby' => 'rand',
          'posts_per_page'=> 1,
      );

      $quotes = new WP_Query( $args );
      $quotes_output = '';

      if( $quotes->have_posts() ):
          while ( $quotes->have_posts() ) :
              $quotes->the_post();
              // Set the temporary post using a WordPress option
              update_option( 'quote_post', get_the_ID() );
          endwhile;
      endif;

      wp_reset_postdata();
}

然后,cron作业将每48小时(人们指出或多或少)触发一次此功能,并设置引号,然后将其显示出来。然后,您的标题可以执行操作以在每次页面加载时显示报价。

add_action( 'display_quote', 'display_quote_function' );
function display_quote_function() {
    // Get the quote post ID
    // The default, 1, will be returned if the option is not set
    $quote_id = get_option( 'quote_post', 1 );

    $quote = get_post( $quote_id ); 
    $quotes_title = quote->post_title;
    $quotes_content = quote->post_content;
    $quotes_output = '<div id="quote"><p>&quot;' . $quotes_content . '&quot;</p><p class="quote-name">' . $quotes_title . '</p></div>';
    echo $quotes_output;
}

do_action('display_quote');