WordPress では投稿の公開日時を予約することができます。しかし、予約投稿がうまく動作しないことがあります。予約投稿が失敗するときの解決方法です。

WordPress の予約投稿の仕組み

予約投稿は cron などで動作しているのではなく、ブログへのアクセスをトリガーにした疑似 cron になっています。
wp-includes/cron.php の wp_cron 関数で現在時刻で実行すべきイベントがあるかチェックしてあればそのイベントに起動します。

予約投稿では予約時刻が過ぎている投稿があると、publish_future_post というイベントが予約日時とともに登録されます。ブログへのアクセス時に wp_cron 関数で publish_future_post というイベントがあり、実行日時を過ぎていると、spawn_cron 関数が呼ばれます。この関数で WordPress のトップレベルにある wp_cron.php に HTTP リクエストを発行します。

wp-cron.php では処理すべきイベントに publish_future_post があると、wp-includes/posts.php の wp_publish_post 関数を呼びます。wp_publish_post 関数では、投稿の状態を公開状態に変更して、管理画面から行うのと同じ処理で編集、保存処理を行います。

予約投稿が失敗するときのチェックポイント

サーバに SSH で接続して、以下のコマンドを実行します。

$ wget http://example.com/wp-cron.php

このコマンドを実行して、サーバレスポンスで 200 が返ってくれば問題ありません。失敗している原因は他にあります。
もし、200 が返って来ないときや、接続ができないようなときはサーバ内から自ドメインの名前解決ができていないことが原因かもしれません。

予約投稿の仕組みで説明したように、WordPress は自分自身に対して HTTP リクエストを出します。そのために自分のドメインがサーバで解決できないとアクセスできずに予約投稿が失敗します。

解決策は /etc/hosts に以下のように指定します。

127.0.0.1 example.com

ググっていると WordPress2.7 にしてから予約投稿が失敗するようになったという現象がちらほらあります。また、wp-includes/cron.php を WordPress2.7 以前のものにすると成功するというような話もあります。これは 2.7 から現在のように HTTP リクエストを出して予約投稿を公開状態にするようになったためだと思われます。

2.7 以前はソケット接続して wp-cron.php を呼び出していました。しかし、予約投稿すると ping が送信されないなどの不具合がありました。多分これを解消するために、通常の編集、保存処理をして公開するように HTTP リクエストを出すようにしたのでしょう。ですので、cron.php を書き換えての対処方法はオススメできません。

関連する投稿