時間が経過してもWP Cronが実行されない


16

目標

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

問題

次のコードはmyにあり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ジョブがスケジュールされていることを確認できます。

コア制御画面

いくつかの変更を行った後、それらをかなり正確に取得することができました。さらに、「今すぐ実行」をクリックすると、実際に受信ボックスに電子メールが届きます。

しかし、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'];
  }
}

このコードの欠点は、ユーザーがこのコードを実行する前に別のページに移動する必要があることです。しかし、反対に、これも機能しないので、それは私の最初の問題ではありません...


1
どこで、どのようにschedule_event( $_SESSION['insert_id'] );解雇されますか?
バンコーダー

ショートコードはページ内に別のファイル(フォームを含む)を含みます。そのフォームがページに再schedule_event( )ロードされると、同じファイルが実行されます。
マイクマダーン

やるいかなる cronsの仕事を?wp_version_checkなど?
バンコーダー

私は取得できませんでした任意の仕事にcronsを。何が問題なのでしょうか?
マイクマダーン

確認するには-コアcronジョブでも失敗しますか?
バンコーダー

回答:


8

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

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

次に、数分ごとにそのページにアクセスするcronジョブを手動で作成する必要があります(共有ホスティング環境の場合はcpanelを使用し、VPS /専用サーバーの場合はターミナルから)。

それがお役に立てば幸いです!


キャッシュプラグインを有効にしました!正確なW3合計キャッシュ
マイクマダーン

14

まず、カスタムcronジョブスケジュールを定義します。

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;
}

これで、カスタムcronタスクの名前を呼び出すだけで済みます。この例では、cronタスク名は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サイトへのトラフィックが十分にあると仮定)。


ノート

cronを適切なタイミングで起動するには、ページにアクセスする必要があります。

例: 30分間隔でタスクをスケジュールしたが、誰も4時間サイトにアクセスしなかった場合、その訪問者が4時間後にサイトにアクセスするまで、cronジョブは実行されません。本当に30分ごとにタスクを実行する必要がある場合は、Webホスティングプロバイダーを介して正当なcronジョブをセットアップし、目的の間隔でWebサイトにアクセスすることをお勧めします。

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ジョブで大きなスクリプトを実行するための大きな利点です。

支援に利用できる機能:


6
これは非常に包括的な応答であり、私が見る限り、実際の質問に対処することができません。これが、スケジュールされたすべてのタスク(コアタスクを含む)が失敗する理由です。
バンコーダー

この答えは、WordPressのcronタスクを正しく理解してスケジュールするための正しい方向にユーザーを導くことです。
マイケルエックランド

4
これは確かに私のワードプレスで多くの理解のcronスケジュールを助けた
マイクMadern

2
マイケル、もっと頻繁に答えるべきです。グレートワン+1
カイザー

1
WP_CronWPの残りの部分と同様に、ボンネットの下でGMTを使用していると思うので、のtime()代わりにで最初のイベントをスケジュールする方が良いでしょうcurrent_time()
イアン・ダン

3

WordPress Cronではタスクをスケジュールできますが、サイトにリクエストがあった場合にのみ実行されます。WordPressが受信するリクエストごとに、処理するcronジョブがあるかどうかを確認し、ある場合/wp-cron.php?doing_wp_cronは、ジョブを非同期に処理するリクエストを実行します。ジョブのスケジュールされた開始がリクエストなしで成功した場合、cronプロセスは開始されません。

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

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

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

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

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

2
doing_wp_cronに値を指定しないと、ジョブが2回実行される可能性が高くなります。それdoing_wp_cron=$(date +\%s.\%N)を防ぐために使用します。
アレクサンダーガーデン

0

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

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

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

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


まだDISABLE_WP_CRON設定していないのでwp-config.php、もっといろいろなことを試して後で戻ってきます
マイク・マダーン

0

Wordpressを非表示にするプラグインを確認します。

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

  1. http(s)://yoursite.com/wp-cron.phpに移動します。空のページが表示されます。完全に空のもの。
  2. さらに、cronジョブマネージャで「次の実行」の下に時間を表示する必要があります:( cronジョブのスケジュール設定-wp-cron.phpが適切に機能する場合 テキスト「キュー内」だけでなく、特定の時間表示される-> cronが機能しません。)

+1。「cronが動作しているかどうかを確認する」プラグインを信じないでください。たとえば、WP Cronステータスチェッカープラグインは、cronが動作していることを示しています。しかし、実際にはそうではありませんでした。 それが示すものは何でも-このプラグインではなく、あなたの目を信じてください!

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.