2007年5月1日星期二

定时是所有 - 在 WordPress 安排任务

WordPress 2.1 的发布带来许多的新的特性,其中一个就是 pseudo-cron - 预定义任务时序安排框架。这已经成为一些定时的通道,Scott Merrill 曾在2005年开发过一个插件叫做 wp-cron 的插件。在 WordPress 2.0 发布之后,在 wp-hachers 邮件列表有个关于在 WordPress 核心代码中添加 cron 类型的时序安排特性的讨论,最后这个特性在 2.1 版本中成形。

这个讨论结果中非常重要的一点是,并不是打算去取代 Linux 操作系统内建的真正的 Cron 特性,也不是打算去达到那种精确

它所提供的是允许插件开发者能够定义事件发生在特定的时间内。它通过当每次页面被导入的时候,检测当前的时间是否在安排任务的时间上来实现这个功能。如果一个设定的时间刚好通过,一个任务(一个回调函数)就会被完成。

开始使用安排任务需要你拥有关于 WordPress 的 hooks, actions 和 filters 的相关知识,如果你还没有,推荐你去阅读下面的文章:

How to schedule a task

在开始之前,需要注意两件重要事情:

  1. 当你安排一个回调函数的时候,你实际上安排了一个会依次调用你函数的自定义动作,具体请查看下面的关于"定义你安排的事件"章节。
  2. 和 actions 和 filters 不一样,预定的任务是永久的。add_action 和 add_filter 的调用需要页面导入,因为他们没有被存储。下面描述的预定的任务集合使用的函数是存储在数据库中,在 wp_options 表中。如果在每次页面导入的时候调用预定义的函数,你将以一个新的预定义的任务结束。因为这个原因,我建议你设置你的预定义任务到你的已激活的回到函数中,具体技巧查看:register_activation_hook.

时序安排允许你安排两种类型的时件:

  1. 简单的未来的事件(如设定在未来的某个时间某篇文章被发表)。
  2. 重复发生的时件,为一定期限内(如一天,一个星期,或者别的)发生的事情设置一个事件(如为 Verse of the day plugin 导入已经解析的 RSS 源)。

安排简单事件

安排一个简单的事件,使用下面的函数:

wp_schedule_single_event( $timestamp, $hook, $args )

$timestamp 是你想这个事件发生的时间戳。 $hook 是自定义的用来调用你的函数的动作技巧(大部分应该在1分钟内完成) $args 是被传给你调用的函数的参数数组,这个参数是可选的。

安排重复发生的事件

使用下面的函数来实现:

wp_schedule_event( $timestamp, $recurrence, $hook, $args )

相同的参数含义和简单事件安排的一样。另加的参数含义如下: $recurrence 用于表示重复类型的字符串。有两种内建的重复类型 -- huorly 和 daily。但是如果你想别的类型,如 weekly?非常幸运的是你可以增加别的类型。cron 系统可以从函数 wp_get_schedules() 得到关于'hourly' 和 'daily' 的信息。 使用 print_r() 输出这个函数的输出,得到下面的结果:

Array  (      [hourly] => Array          (              [interval] => 3600              [display] => Once Hourly          )        [daily] => Array          (              [interval] => 86400              [display] => Once Daily          )  )  

就如你所见的,所有的都是用内部的时间(多少秒)去设置多频繁事件发生。查看 wp_get_schedules() 的源代码,你将发现它实际上合并了两个的 corn_schedule filter 的到一个数组,并输出它(这里翻译有点问题),这样子的话如果你能够实现一个 filter function 的话,那么就能 hooks 到 cron_schedules hook,你就能增加到列表中。

增加 weekly 和 fortnightly 作为一个可用的资源,使用下面的代码:

function more_reccurences() { return array( 'weekly' => array('interval' => 604800, 'display' => 'Once Weekly'), 'fortnightly' => array('interval' => 1209600, 'display' => 'Once Fortnightly'), ); } add_filter('cron_schedules', 'more_reccurences');

再次使用 print_r() 输出这个函数的输出,得到下面的结果:

Array  (      [weekly] => Array          (              [interval] => 604800              [display] => Once Weekly          )        [fortnightly] => Array          (              [interval] => 1209600              [display] => Once Fortnightly          )        [hourly] => Array          (              [interval] => 3600              [display] => Once Hourly          )        [daily] => Array          (              [interval] => 86400              [display] => Once Daily          )  )

定义你要安排的事件。

关于这点,为了创建一个列子,让我们设想安排一些每天都发生的事件,并把这个每天发生的事件叫做 my_daily_function()。所以我们将增加下面这些代码到我们的插件:

if (!wp_next_scheduled('my_daily_function_hook')) { wp_schedule_event( time(), 'daily', 'my_daily_function_hook' ); }

就像上面所说的,我在这里做的是每天 'my_daily_function_hook' 会被调用,并且这是非常重要这个函数只需调用一次,这就是这个原因去检查 wp_next_scheduled('my_daily_function_hook') 返回的结果是否为否。那个函数将返回下次安排的时间,如果没有被安排返回否,我们要确保那个事件只被安排一次。

我们现在需要定义一个动作去调用 my_daily_function(),我需要定义一个自定义动作。

add_action( 'my_daily_function_hook', 'my_daily_function' );

和函数本身

function my_daily_function() { print "I was just called. I'll be called at the same time tomorrow"; }

就这些。在每天相同的时间(当这个插件第一次被导入),第二个浏览站点任何页面的人将看到有文字显示在页面上。查看一个正在被使用的时序安排的列子,请查看 wp-votd plugin code。在那里你将看到安排的时间调用 inside _install() 方法以致它只被调用一次。

就是上面所说的,wp_schedule_event 还可以有第四个可选的函数,就是给回调函数传递一个数组参数。

打包所有

时序安排的功能是一个对插件开发者来说非常棒的 WordPress 新特性,它能够使我们所做的变得更简单,它能保持一个最新版的计时器在 wp-option 表中,并能比较现在的和预定义之间的区别。主要荣誉应该给与把它加入核心代码中的开发者,还有Scott Merrill,他开发了原始版的 cron 插件

我希望这个教程能够对你有所帮助,请把该修正的地方,问题,使用方法和想法在留言中告诉我,让我们大家一起分享吧!



Orignal From: 定时是所有 - 在 WordPress 安排任务