WordPressでWP-Cronを使った自動実行をする方法:wp_schedule_event()

WordPressには、スクリプトを定期実行するためのシステム「WP-Cron」が用意されています。 目次 ・WP-CronとCronの違い ・WP-Cronで使う関数 ・WP-Cronを使った2種類の実装サンプル ・WP-Cronイベントを確認する

WP-CronとCronの違い

Linuxサーバーの場合は、Cronを使ってスケジュール管理することもでできるのですが、サーバーをいじることができない等Cronを使えない環境もあります。 そのような時に、WP-Cronを使うと簡単にスクリプト実行のスケジュール管理をすることができます。

WP-Cronの特徴

・指定時間を過ぎた最初のアクセス時に実行される ・そのため、指定時間に必ず実行される保証はない そのため、アクセスがあまりないサイトでは実行が遅延しがちになるという点に注意です。また、ローカル開発環境だと正常に動作しないことがあるようです。

WP-Cronで使う関数

WP-Cronには、スケジュールを登録する wp_schedule_event() 関数と、スケジュールが登録されているかを確認する wp_next_scheduled()、スケジュールを削除するwp_clear_scheduled_hook() などが用意されています。

wp_schedule_event()

wp_schedule_event(実行する時間, 実行間隔, フック, フックに渡す値);
第1引数「実行する時間」:最初に処理を実行する時間をUNIX時間で指定 第2引数「実行間隔」:1時間毎(hourly)、毎日(daily)など実行間隔を指定 第3引数「実行する関数」:フック名を指定 第4引数「実行関数に渡す値」:第3引数のフックに渡す値を指定 *オプション wp_schedule_event() でフックを登録し、登録したフックに関数を登録し処理を実行するという流れになります。 以下では、time()関数で現在のUNIX時間を指定しているので、即時cron_sample_action()が実行されます。
//WP-Cronのフック(cron_sample_hook)を登録
wp_schedule_event(time(), "daily", "cron_sample_hook");

//cron_sample_hookフックで実行する関数を指定
add_action('cron_sample_hook', 'cron_sample_action');

function cron_sample_action() {
    //フックで実行する処理を記述
}

WP-Cronを使った2種類の実装サンプル

今回は、プラグインとして実装するサンプルとfunctions.phpから読み込むサンプルの2つを紹介します。

プラグインとしてWP-Cronを使うサンプル

プラグインとしてWP-Cronを登録するサンプルです。プラグイン有効化・無効化時に、スケジュールを登録・削除できます。
//プラグインを有効化した時に実行
if(function_exists('register_activation_hook')) {
    register_activation_hook(__FILE__, 'register_sample_cron');
}

//WP-Cronのフックをwp_schedule_event()で登録
function register_sample_cron() {
    // イベントが未登録なら登録する
    if(! wp_next_scheduled('daily_sample_event')){
        wp_schedule_event(time(), 'daily', 'daily_sample_event');
    }
}

//daily_sample_eventで実行する関数
function daily_sample_action() {
    wp_insert_post(array(
        "post_title"   => "WP-Cronテスト",
        "post_status"  => "pending",
        "post_content" => "WP-Cronのテストです"
    ));
}

//プラグインの無効化時にWP-Cronスケジュールを削除
if(function_exists('register_deactivation_hook')) {
    register_deactivation_hook (__FILE__, 'remove_sample_cron');
}

functions.phpからWP-Cronを使うサンプル

Sample_Cronというクラスを定義し、WP-Cronを登録するサンプルです。 基本的にはプラグインのサンプルと同じですが、利用するフックが異なります。
//プラグインのサンプルと違い適当なフックがないので、
//Sample_Cronクラスが存在しなかったらWP-Cronイベントを削除します
if (! class_exists("Sample_Cron")){
    wp_clear_scheduled_hook('daily_sample_event');
} else {
    new Sample_Cron;
}

class Sample_Cron{
    function __construct(){
        add_action('wp', array($this, 'set_sample_cron'));
        add_action('daily_sample_event', array($this, 'daily_sample_action'));
    }

    function set_sample_cron() {
        // イベントが未登録なら登録する
        if(! wp_next_scheduled('daily_sample_event')){
            wp_schedule_event(time(), 'daily', 'daily_sample_event');
        }
    }

    function daily_sample_action() {
     // テスト用の投稿をするサンプル処理
        wp_insert_post(array(
            "post_title"   => "WP-Cronテスト",
            "post_status"  => "pending",
            "post_content" => "WP-Cronのテストです"
        ));
    }
}

WP-Cronイベントを確認する

WP-Cronに登録したスケジュールを確認する方法には、プラグインで確認する方法とデータベースから確認する方法の2つがあります。

「WP Crontrol」プラグインを使って確認する

「WP Crontrol」プラグインでは、スケジュールの確認・追加・削除・編集など一通りの機能が揃っています。

WP-Cronスケジュールをデータベースから確認する

WP-Cronのスケジュールは、wp_optionsテーブルの option_name = cron に保存されています。 option_value は、配列がシリアライズされているので、unserialize()関数でデコードしてあげるか、get_option()関数を使うと良いです。
$cron = get_option('cron');
var_dump($cron);
以下は、var_dump()で表示した内容の抜粋です。

["wp_version_check"]=>
array(1) {
  ["40cd750bba9870f18aada2478b24840a"]=>
  array(3) {
    ["schedule"]=>
    string(10) "twicedaily"
    ["args"]=>
    array(0) {
    }
    ["interval"]=>
    int(43200)
  }
}