我在数据库中保存了一系列报价,我希望每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>"' . $quotes_content . '"</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小时才能再次更改报价。我觉得这里可能缺少一些简单的东西。
答案 0 :(得分:1)
您的问题很可能是这样:
if ( ! wp_next_scheduled( 'quote_cron_hook' ) ) {
wp_schedule_event( time(), 'every_two_days', 'quotes_cron_hook' );
}
在您有quote_cron_hook
个quotes_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>"' . $quotes_content . '"</p><p class="quote-name">' . $quotes_title . '</p></div>';
echo $quotes_output;
}
do_action('display_quote');