web-dev-qa-db-ja.com

WP 時間が経過するとCronが実行されない

目標

ユーザーがフォームを送信してから8分後にwp_schedule_single_event( )を使用して電子メールを送信する単一のイベントを実行します。

問題

次のコードは私のfunctions.phpにあります。

function nkapi_send_to_system( $args ) {
  wp_mail( 'xxx', 'xxx', $args );
}

add_action( 'nkapi_send', 'nkapi_send_to_system' );

function schedule_event( $id ) {
  wp_schedule_single_event( current_time( 'timestamp' ) + 480, 'nkapi_send', array( $id ) );
}

そして、次のコードはschedule-eventを呼び出すために使用されます。

schedule_event( $_SESSION['insert_id'] ); // the $_SESSION var contains an INT

8分以上待った後、受信トレイに電子メールが届きませんでした。

私が試したこと

プラグイン Core Control を使うと、どのcronジョブがスケジュールされているかを見ることができます。

Core Control screen

いくつかの変更を加えたところ、「今すぐ実行」をクリックしたときに非常に正確で、さらに良いものになったので、実際には受信トレイに電子メールが届きます。

しかし、8分後にサイトにアクセスしてもcronが実行されないのはなぜですか。このコードの何が問題になっていますか私はWP Cronを使ったのは今回が初めてだということを言わなければなりません。

もっと試してみた

vancoder idのコメントの後、次のコードを直接functions.phpに入れると、コードが機能するかどうかをテストすることにしました。

function schedule_event( $id ) {
  wp_schedule_single_event( time(), 'nkapi_send', array( $id ) );
}

if ( isset( $_SESSION['insert_id'] ) ) {
  if ( ! array_key_exists( 'insert_scheduled', $_SESSION ) || $_SESSION['insert_scheduled'] != $_SESSION['insert_id'] ) {
    schedule_event( $_SESSION['insert_id'] );
    $_SESSION['insert_scheduled'] = $_SESSION['insert_id'];
  }
}

このコードの欠点は、このコードが実行される前にユーザーが別のページに移動しなければならないことです。しかし、反対に、これもうまくいかないので、それは私の最初の問題ではないでしょう...

16
Mike Madern

まず、キャッシングプラグインが有効になっていないことを確認してください。あなたの訪問者にはライブページではなくあなたのページのキャッシュされたバージョンが提供されるので、プラグインをキャッシュすることはクーロンジョブに干渉することができます。

キャッシングプラグインを有効にしている場合は、自分のページの1つを選択し、そのページのキャッシングプラグインの設定に除外を追加して、キャッシュされないようにすることができます。

その後、手動でcronジョブを作成して(共有ホスティング環境にいる場合はcpanelを使用し、VPS /専用サーバーの場合は端末から)、数分ごとにそのページにアクセスします。

私はそれが役立つことを願っています!

8
WPMU-DEV Ari

最初に、あなたのカスタムクーロンジョブスケジュールを定義します。

add_filter('cron_schedules', array($this, 'cron_schedules'));

public function cron_schedules($schedules){
    $prefix = 'cron_';// Avoid conflict with other crons. Example Reference: cron_30_mins
    $schedule_options = array(
        '30_mins' => array(
            'display' => '30 Minutes',
            'interval' => '1800'
        ),
        '1_hours' => array(
            'display' => 'Hour',
            'interval' => '3600'
        ),
        '2_hours' => array(
            'display' => '2 Hours',
            'interval' => '7200'
        )
    );
    /* Add each custom schedule into the cron job system. */
    foreach($schedule_options as $schedule_key => $schedule){
        $schedules[$prefix.$schedule_key] = array(
            'interval' => $schedule['interval'],
            'display' => __('Every '.$schedule['display'])
        );
     }
     return $schedules;
}

実際にどこでいつイベントをスケジュールするかを決める必要があります。

これは、カスタムクラスメソッドを呼び出すコードの一例です。

$schedule = $this->schedule_task(array(
    'timestamp' => current_time('timestamp'), // Determine when to schedule the task.
    'recurrence' => 'cron_30_mins',// Pick one of the schedules set earlier.
    'hook' => 'custom_imap_import'// Set the name of your cron task.
));

これは実際にイベントをスケジュールするコードです。

private function schedule_task($task){
    /* Must have task information. */
    if(!$task){
        return false;
    }
    /* Set list of required task keys. */
    $required_keys = array(
        'timestamp',
        'recurrence',
        'hook'
    );
    /* Verify the necessary task information exists. */
    $missing_keys = array();
    foreach($required_keys as $key){
        if(!array_key_exists($key, $task)){
            $missing_keys[] = $key;
        }
    }
    /* Check for missing keys. */
    if(!empty($missing_keys)){
        return false;
    }
    /* Task must not already be scheduled. */
    if(wp_next_scheduled($task['hook'])){
        wp_clear_scheduled_hook($task['hook']);
    }
    /* Schedule the task to run. */
    wp_schedule_event($task['timestamp'], $task['recurrence'], $task['hook']);
    return true;
}

今、あなたがする必要があるのはあなたのカスタムクーロンタスクの名前への電話をかけることだけです。この例では、クーロン・タスク名はcustom_imap_importです。

add_action('custom_imap_import', array($this, 'do_imap_import'));

public function do_imap_import(){
    // .... Do stuff when cron is fired ....
}

そのため、この例では、$this->do_imap_import();が30分ごとに呼び出されます(Webサイトへのトラフィックが十分にあると仮定して)。


ノート

あなたのクーロンが正しい時間に発射するためにページ訪問を必要とします。

例: 30分間隔でタスクをスケジュールしたが、4時間誰もあなたのサイトにアクセスしなかった場合、そのビジターが4時間後にあなたのサイトに来るまであなたのcronジョブは実行されません。あなたが本当にあなたの仕事が本当に30分毎に発射されるのを必要とするならば、それは望ましい間隔であなたのウェブサイトを訪問するためにあなたのウェブホスティングプロバイダーを通して正当なクーロン仕事を始めることを勧めます。

WordPressのcronジョブはあなたのウェブサイトを遅くしません!

Cronスクリプトが実行されるのに長い時間がかかる場合、訪問者はスクリプトが実行されるまで待たなければならないのでしょうか。いや!それはどうして可能でしょうか。 wp-cron.phpファイルを見ると、行が見つかります。

ignore_user_abort(true);

これはphp.ini設定で、サイト/スクリプトのロードを停止してもスクリプトは実行を停止しません。

wp-includes/cron.phpファイルを見ると、次のような行が見つかります。

wp_remote_post( $cron_url, 
array('timeout' => 0.01,
 'blocking' => false, 
 'sslverify' => apply_filters('https_local_ssl_verify', true)) );

つまり、WordPressは実行をトリガーするために0.01秒だけ待機してから中止しますが、ignore_user_aborttrueに設定しているのでスクリプトは実行されます。この機能は、WordPressのcronジョブで大きなスクリプトを実行するという大きな利点です。

援助に利用できる機能:

14
Michael Ecklund

WordPress Cronはあなたがタスクをスケジュールすることを可能にしますが、それらはサイトへのリクエストがある場合にのみ実行されます。 WordPressが受け取るリクエストごとに、処理するcronジョブがあるかどうかを確認し、もしあれば、ジョブを処理するために非同期で/wp-cron.php?doing_wp_cronへのリクエストを起動します。ジョブのスケジュールされた開始が要求なしで成功した場合、cronプロセスは開始されません。

スケジュールされたジョブを見て実行することができるので、特にcachingプラグインを使用している場合は、cronジョブの開始をトリガーする要求がない可能性があります。より定期的なスケジュールにこれをオフロードするための最良の選択肢は、WordPressのデフォルトチェックを無効にしてcrontabを使用することです。

最初にデフォルトのチェックを無効にするために(これはクライアント側のパフォーマンスを少し向上させることができます)、以下をwp-config.phpに追加します。

// Disable default check for WordPress cron jobs on page loads
define( 'DISABLE_WP_CRON', true );

次に、1分に1回wp-cron.phpページを取得してバックエンドのジョブを処理するタスクを作成し、コマンドラインからcrontab -eと入力して、次のような行を追加します。

*/1 * * * * /usr/bin/curl --silent http://example.com/wp-cron.php?doing_wp_cron=$(date +\%s.\%N) >/dev/null 
3
doublesharp

Wordpressを隠すプラグインをチェックしてください。

これが問題かどうかを確認する方法は?

  1. Http(s)://yoursite.com/wp-cron.phpに移動します。空のページが表示されます。完全に空のもの。
  2. あなたはクーロンジョブマネージャで「次の実行」の下で時間を見なければならないほかに: Cron job scheduled - if wp-cron.php works properly  ( "In queue"というテキストだけではなく - 与えられた時間 - "In queue"というエントリはたまに問題ない場合がありますが、それが唯一の原因である場合 - > cronが機能しない)

+1。 「cronが動作しているかどうかを確認する」ようなプラグインは信じないでください。 WP cronステータスチェッカープラグインは、cronが機能していることを示しました。しかし実際にはそうではありませんでした。 Whatever it shows - believe your eyes and not this plugin! 

結論:それが404エラーである場合 - それから他の人が示唆しているようにa)プラグインをキャッシュするだけでなく、Wordpressを隠すプラグインもオフにします。

0
Peter Cz

設定でDISABLE_WP_CRONが設定されていないことを確認してください。

それに失敗したら、すべてのプラグインを無効にして(コアコントロールを除く - 私はwp-crontrolを使用します)、コアジョブが機能するかどうか確認してください。もしそうなら、どこかにプラグインの干渉があります。

同様に、標準のTwentysomethingテーマに切り替えてみてください。

これらのどれもに違いが出ない場合は、それがホスティングの問題である可能性があります。

0
vancoder