wp_next_scheduled() は、WP-Cron(WordPress の予約した処理を動かす仕組み)に予約した処理が、次に動く時刻を調べる関数です。予約がなければ false が返るので、wp_schedule_event() と組み合わせて、同じ処理を二重に予約しないようにするのによく使います。
書き方
wp_next_scheduled( string $hook, array $args = array() ): int|false
$hook:予約したときのフック(アクション)の名前$args:予約したときに渡した引数。予約したときと同じ配列を渡す- 戻り値:次に動く時刻の UNIX 時刻(1970 年 1 月 1 日からの秒数)。予約がなければ false
使い方の例
作業環境(WordPress 7.1.3)で試した結果を、コメントに書いています。試したあと、予約した処理は wp_clear_scheduled_hook() で消し、wp_next_scheduled() が false に戻ったことを確認しています。
二重に予約しないように登録する
いちばんよく使う形です。init のたびに予約があるかを確認し、なければ予約します。作業環境で、この関数を続けて 2 回呼んでも、予約は 1 つだけでした。
<?php
// 1 日 1 回動かす処理を、二重に予約しないように登録する
add_action( 'init', 'my_schedule_daily_task' );
function my_schedule_daily_task() {
if ( ! wp_next_scheduled( 'my_daily_task' ) ) {
wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'my_daily_task' );
}
}
add_action( 'my_daily_task', 'my_run_daily_task' );
function my_run_daily_task() {
// 1 日 1 回する処理
}
次に動く時刻を調べる
<?php var_dump( wp_next_scheduled( 'my_daily_task' ) ); // bool(false)(まだ予約していない) wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'my_daily_task' ); $ts = wp_next_scheduled( 'my_daily_task' ); echo $ts; // 1793082151(UNIX 時刻) echo wp_date( 'Y-m-d H:i:s', $ts ); // サイトのタイムゾーン(Asia/Tokyo)の日時で表示 echo wp_get_schedule( 'my_daily_task' ); // daily(間隔の名前)
確認せずに予約すると重なる
wp_next_scheduled() で確認せずに wp_schedule_event() を呼ぶと、時刻が違えば同じ処理がいくつでも予約されます。ページを開くたびに予約していると、気づかないうちに同じ処理が何度も動きます。
<?php // 確認せずに続けて予約すると、時刻が違えばいくつでも予約される wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'my_daily_task' ); // true wp_schedule_event( time() + 2 * HOUR_IN_SECONDS, 'daily', 'my_daily_task' ); // true wp_schedule_event( time() + 2 * DAY_IN_SECONDS, 'daily', 'my_daily_task' ); // true // → my_daily_task が 3 つ予約され、1 日に 3 回動く echo wp_clear_scheduled_hook( 'my_daily_task' ); // 3(消した数)
$args も同じでないと見つからない
WP-Cron は、フックの名前と $args の組み合わせで予約を見分けます。$args を付けて予約したものは、同じ $args を渡さないと見つかりません。
<?php // $args を付けて予約したものは、同じ $args で探さないと見つからない wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'my_daily_task' ); wp_schedule_event( time() + 2 * HOUR_IN_SECONDS, 'hourly', 'my_daily_task', array( 'post_type' => 'my_article' ) ); echo wp_next_scheduled( 'my_daily_task' ); // 1 つ目の時刻($args なしのもの) echo wp_next_scheduled( 'my_daily_task', array( 'post_type' => 'my_article' ) ); // 2 つ目の時刻 var_dump( wp_next_scheduled( 'my_daily_task', array( 'post_type' => 'post' ) ) ); // bool(false) // 消すときも $args ごとに echo wp_clear_scheduled_hook( 'my_daily_task' ); // 1 echo wp_clear_scheduled_hook( 'my_daily_task', array( 'post_type' => 'my_article' ) ); // 1
プラグインを止めるときに予約を消す
予約は、プラグインやテーマを止めてもデータベースに残ります。止めるときに消しておくと、動かない予約が残り続けません。
<?php
// プラグインを止めるときは、予約も消す(メインのファイルに書く)
register_deactivation_hook( __FILE__, 'my_unschedule_daily_task' );
function my_unschedule_daily_task() {
wp_clear_scheduled_hook( 'my_daily_task' );
}
予約投稿の公開の予定を調べる
ここからの 2 つの節では、WP-Cron に入っている処理を「予定」と呼びます(上の節の「予約」と同じものです)。予約投稿を保存すると、WordPress は publish_future_post というフックの予定を 1 つ登録します。$args は投稿の ID が 1 つだけ入った配列です。そのため、array( 投稿の ID ) を渡すと、その投稿が公開される予定の時刻が分かります。
<?php // 予約投稿(ID は 123 とする)の公開の予定を調べる $ts = wp_next_scheduled( 'publish_future_post', array( 123 ) ); echo $ts; // 1793941599(UNIX 時刻) echo wp_date( 'Y-m-d H:i:s', $ts ); // 2026-11-06 14:06:39(投稿の日時と同じ) // ID を文字で渡すと見つからない var_dump( wp_next_scheduled( 'publish_future_post', array( '123' ) ) ); // bool(false) // $args を省いても見つからない var_dump( wp_next_scheduled( 'publish_future_post' ) ); // bool(false)
作業環境で試すと、予定の時刻は、投稿の post_date_gmt を UNIX 時刻にしたものと同じでした。公開されると予定は消え、false が返ります。
予約投稿と予定を並べて見る
予約投稿が「予約済み」のまま残っているときに、予定があるのに動いていないのか、予定そのものがないのかを分けて見る例です。
<?php
// 予約済みの投稿ごとに、公開の予定と、時刻を過ぎているかを出す
$posts = get_posts( array(
'post_status' => 'future',
'numberposts' => -1,
'orderby' => 'date',
'order' => 'ASC',
) );
foreach ( $posts as $post ) {
$ts = wp_next_scheduled( 'publish_future_post', array( $post->ID ) );
$late = strtotime( $post->post_date_gmt . ' GMT' ) <= time();
printf(
"%d\t%s\t%s\t%s\n",
$post->ID,
$post->post_date,
$ts ? wp_date( 'Y-m-d H:i', $ts ) : '予定なし',
$late ? '時刻を過ぎている' : ''
);
}
WP-Cron を止めている作業環境で動かすと、時刻を過ぎた予約投稿が、予定を持ったまま残っていました。この形なら、予定はあるので、WP-Cron が動いていないほうを疑います。「予定なし」と出る投稿は、予定が消えているので、投稿を保存し直すと予定が入り直ります。
気をつけること
- WP-Cron は、だれかがサイトのページを開いたときに、時刻を過ぎた予約を動かします。時刻を過ぎても、ページが開かれるまでは動きません。アクセスの少ないサイトや、決まった時刻に動かしたい処理は、サーバーの cron(決まった時刻にコマンドを動かすサーバーの機能)から wp-cron.php を開くようにしてください。
- wp-config.php で
DISABLE_WP_CRONを true にしているサイトでは、ページを開いても予約は動きません。サーバーの cron から動かしているかを確認してください。 - 戻り値は UNIX 時刻なので、日時で見るときは
wp_date()を使うと、サイトのタイムゾーンで表示できます。 - 同じフック・同じ $args・同じ時刻のものを続けて予約すると、2 つ目は false が返りました(作業環境で確認した結果)。時刻が違うと予約されるので、
wp_next_scheduled()で確認する形にしておくのが確かです。 - 予約の一覧を画面で見たいときは、WP-Cron の予約を一覧で表示するプラグインを使うと、フック・次の時刻・間隔をまとめて確認できます。
- 予約投稿の予定(
publish_future_post)は、$args がarray( 投稿の ID )です。ID は数字で渡します。array( '123' )のように文字で渡すと、同じ投稿でも見つかりません(作業環境で確認した結果)。

