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-cron起動(クーロン)で使う関数
wp-cronを起動する関数には、
- wp_schedule_event
- wp_schedule_single_event
の2つがあります。
wp_schedule_event
「wp_schedule_event」は、同じことをリピートしたい場合に使います。特に「毎週・毎日・毎時間・毎分」などの場合に使うと便利です。
フォーマットは以下のとおりです。
- $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日後・毎月特定の日など)の場合に使います。
フォーマットは以下のとおりです。
- $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タイムで指定する必要があります。
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の関数です。 スケジ ...