SEOノウハウ・副業ブログ・ワードプレス

WordPressでクーロン(wp-cron)を実行させる方法【スケジュールを自動起動できる】

2018年5月3日

WordPress(ワードプレス)にはクーロンと同じ動きができる「wp-cron」という機能があります。

これを使うと、「指定の時間」に「指定の処理を実行する」ことができるようになり、いろいろなプログラムを自動で実行できます。

例えば、時間がかかるバッチ処理を、夜中のアクセスが少ない時間に実行すれば、サイトにかかる負荷を軽減できます。

そこで、この記事では「wp-cron」を使ってスケジュール登録する方法と使い方について紹介します。

wp-cronの起動の仕組み

WordPressのwp-cronはサーバーのcronとは違い、サイトにアクセスがあった時にスケジュール登録が行われ、その後に指定の時間になると処理が実行されます。

  • 1)サイトにアクセスがあった時に「スケジュール登録」
  • 2)指定の時間になったら「スケジュール実行」

例えば、以下のように9時に実行したいスケジュールがあっても、そこまでにサイトにアクセスがなかった場合、アクセスがあった時点(9時1分)で処理が実行されます。

経過時刻 実行内容
08:50 ①09:00に実行するスケジュールをプログラム記載
②10:00に実行するスケジュールをプログラム記載
09:00 ①も②もスケジュール設定後にサイトアクセスがないので処理が実行されない
09:01 サイトにアクセスあり
①と②がスケジュール登録される
09:01 ①で設定したスケジュールが実行される
10:00 ②で設定したスケジュールが実行される

上記から分かる通り、アクセスがないサイトの場合は、スケジュールが思い通りに実行されないことがあります。

これにより、思い通りに実行できないことがある点に注意が必要です。

アクセスが少ないサイトの場合、自分でページや管理画面にアクセスして実行させることはできます。

便利なプラグイン「WP Control」

「WP Control」は、現在登録されているスケジュールを確認、実行、編集、削除ができます。

スケジュール登録したwp-cronを操作できるので、テストで使えます。入れておくと何かと便利です。

WP Control

wp-cron起動(クーロン)で使う関数

wp-cronを起動する関数には、

  • wp_schedule_event
  • wp_schedule_single_event

の2つがあります。

wp_schedule_event

「wp_schedule_event」は、同じことをリピートしたい場合に使います。特に「毎週・毎日・毎時間・毎分」などの場合に使うと便利です。

フォーマットは以下のとおりです。

bool wp_schedule_event( int $timestamp, string $recurrence, string $hook [ , array $args = array() ] )


  • $timestamp:開始日時
  • $recurrence:繰り返し間隔
  • $hook:実行時する関数名

$recurrence(繰り返し間隔)には、すでに用意されている文字列があり、以下の文字列を指定できます。

  • hourly(1時間に1回)
  • twicedaily(1日に2回)
  • daily(1日に1回)
  • weekly(1週間に1回)

残念ながら「monthly(1か月に1回)」はありません。

ですが、functions.phpに以下のコードを追加することで「monthly」を指定できるようになります。

function my_add_intervals($schedules) {
  $schedules['monthly'] = array(
      'interval' => 2678400,
      'display' => __('1ヶ月(31日)に1度実行')
  );
  return $schedules;
}
add_filter( 'cron_schedules', 'my_add_intervals');

上記のスケジュールに複数スケジュールを追加する場合は下記のように書くことができます。

intervalは、秒数で追加します。

function my_add_intervals($schedules) {
  $schedules['monthly'] = array(
      'interval' => 2678400,
      'display' => __('1ヶ月(31日)に1度実行')
  );
  $schedules['20sec'] = array(
      'interval' => 20,
      'display' => __( '20秒に1度実行' )
  );
  return $schedules;
}
add_filter( 'cron_schedules', 'my_add_intervals');

上記の例では、60秒以下の設定を追加していますが、60秒以下の設定は基本的にうまく動きません(あくまでサンプルです)。

wp_schedule_single_event

「wp_schedule_single_event」は、繰り返しがない場合や、変則的なスケジュール(15日後・毎月特定の日など)の場合に使います。

フォーマットは以下のとおりです。

bool wp_schedule_single_event( int $timestamp, string $hook [ , array $args = array() ] )


  • $timestamp:実行日時
  • $hook:実行時する関数名

基本的には「繰り返し」を行わない場合に利用するのですが、$timestampを動的に取得することで、繰り返しにすることも可能です。

例えば、$timestampを以下のように固定すると指定の日時にしか実行されません。

wp_schedule_single_event( strtotime(date('2024-08-01 9:00:00')), 'twitter_hoge_add_cron' );//18時00分

ですが、以下のように動的に取得させると、繰り返し実行が可能になります。

mktimeの「date('m') + 1」を使って、一か月後に予約するようになっています。

wp_schedule_single_event( strtotime(date('Ymd H:00:00', mktime(9, 0, 0, date('m') + 1, 1, date('Y')))), 'twitter_hoge_add_cron' );//18時00分

なお、「wp_schedule_single_event」を使う場合は、「スケジュール2重登録防止」の設定が必須です。

wp-cronの基本的な書き方

「wp_schedule_event」でスケジュール登録し、スケジュールで実行したい関数とスケジュールを「add_action」で関連付けます。

「wp_next_scheduled」を使ってすでにスケジュールの重複登録を防ぐようにします。

function hoge_function() {
    //実行したい内容
}
add_action ( 'hoge_add_cron', 'hoge_function' );

//スケジュール2重登録防止
if ( !wp_next_scheduled( 'hoge_add_cron' ) ) {
    //指定した時間と日本での実行時間には9時間差がある
    //3:00:00を指定すると日本時間の12時に実行される
    wp_schedule_event( strtotime(date("Ymd 3:00:00")), 'daily', 'hoge_add_cron' );
}

「wp_schedule_event」の最初の引数(日時を指定する変数)は、スケジュールを実行したい時間をUTCで登録します。

一度実行すると2つ目の引数に設定された間隔でリピート実行されます。

三つ目に設定した引数で指定した関数が実行されます。

※リピート起動もアクセスがあったタイミングが実行タイミングなので、アクセスがないサイトだと起動しません。

UNIXタイム

WordPressのクーロンは、スケジュール設定時にUNIXタイムを指定します。

PHPで、UNIXタイムで特定時刻を指定する方法

//今日の2時をUNIXタイムにする
$tt = strtotime(date('Ymd 02:00:00'));

また、Wordpressで登録する日付はUNIXタイムで、日本時間とは9時間の差があります。

メモ

日本時間は「UNIXタイム+9時間」

日本時間の朝9時にクーロンを起動したい場合は、-9時間した日付をUNIXタイムで指定する必要があります。

例:日本の朝4時に起動させたい場合

strtotime(date('Ymd 19:00:00'));

WordPressで扱う日付については、下記を参考にしてください。

WordPressの日付・時刻の取得【unixtimeとローカル時刻の取得】

unixtimeと日本のローカル時刻では、9時間の違いがあります。 WordPressでどの関数でどの日時を取得できるかを知っておかないと、日付データの設定する時にうまくいきません。 WordPres ...

「wp_schedule_single_event」でリピート起動する

「wp_schedule_single_event」は最初のarg(日時を指定する変数)に指定した時刻に1度だけスケジュールを実行します。

1度だけ起動するのは、日付を固定日付にした場合で、日付を「動的」に設定すれば、好きな時に1度だけ起動するリピート起動のようなこともできます。

動的にする場合は「mktime」を使うと便利です。

下記の例だと15分ごとにスケジュール起動します。

function hoge_function() {
    //実行したい内容
}
add_action ( 'hoge_add_cron', 'hoge_function' );

//スケジュール2重登録防止
if ( !wp_next_scheduled( 'hoge_add_cron' ) ) {
    //9時間差がある
    wp_schedule_single_event( strtotime(date('Ymd H:00:00', mktime(date('H'), date('i')+15, 0, date('m'), date('d'), date('Y')))), 'hoge_add_cron' );//7時
}

下記の例だと15日ごとにスケジュール起動します。

function hoge_function() {
    //実行したい内容
}
add_action ( 'hoge_add_cron', 'hoge_function' );

//スケジュール2重登録防止
if ( !wp_next_scheduled( 'hoge_add_cron' ) ) {
    //15日の9時に実行される
    wp_schedule_single_event( strtotime(date('Ymd H:i:s', mktime(0, 0, 0, date('m')+1, 15, date('Y')))), 'hoge_add_cron' );
}

メモ

mktimeで「date('m')+1」と指定しているので、翌月からスタートになります。当月分は自分で起動させる必要があります。

エラーがでる場合

起動した場合に出たエラーと解決方法を紹介しておきます。

Maximum execution time of 60 seconds exceeded

Fatal error: Maximum execution time of 60 seconds exceeded

などのエラーがでる場合があります。処理時間がオーバーする場合は、処理時間を延長させることで回避できます。

set_time_limitで処理時間に3600(1時間)を設定しておけばほとんとの場合は問題ないと思います。

参考:処理時間の延長方法

問題:予期しない HTTP 応答コード: 401

サイトの WP-Cron システムへの呼び出しが頻発する問題がありました。 つまり、サイトの WP-Cron イベントが機能しない可能性があります。
問題:予期しない HTTP 応答コード: 401。

サイトをBasic認証で非公開にしている場合に起こります。htaccessで特定IPだけ許可するか、Basic認証を取っ払うか。

特にテスト環境でやっている場合は、本番で稼働させればうまくいくことがあります。

//指定のドメインでなければ処理終了
if($_SERVER['HTTP_HOST']!='xxxxxx.com') {
    exit(1);
}

などを使って、本番環境でのみ起動するように修正が必要になります。

wp_schedule_eventで登録したコールバック関数の中身をデバッグする方法【メモ】

WordPressでは疑似クーロン(wp-cron)を使って、一定時間経過後に関数(コールバック関数)を呼び出すタイマー機能を実装できます。 そこで使うのが下記のWordPressの関数です。 スケジ ...

  • B!