WordPress 內建的 WP-Cron 是一套基於資料庫的偽定時任務系統,支援循環與單次排程,驅動核心功能如定時發文、版本檢查、清理暫存。本文系統整理所有核心 API、參數詳解、頻率擴展方法與實戰調試技巧,是主題/外掛開發者的必備參考。
wp_options 表 cron 選項,每次 HTTP 請求檢查到期任務並執行。do_action( $hook, $args )。| 函數 | 簽名 | 用途 |
|---|---|---|
wp_get_schedule |
wp_get_schedule( $hook, $args = array() ) |
獲取指定鉤子的排程頻率(如 'hourly'),無排程返回 false |
wp_get_schedules |
wp_get_schedules() |
獲取所有已註冊的頻率列表(含自定義) |
wp_next_scheduled |
wp_next_scheduled( $hook, $args = array() ) |
獲取下次執行時間戳(整數),常用於防重複註冊 |
wp_schedule_event |
wp_schedule_event( $timestamp, $recurrence, $hook, $args = array() ) |
註冊循環任務 |
wp_schedule_single_event |
wp_schedule_single_event( $timestamp, $hook, $args = array() ) |
註冊單次任務 |
wp_unschedule_event |
wp_unschedule_event( $timestamp, $hook, $args = array() ) |
取消指定時間的任務 |
wp_clear_scheduled_hook |
wp_clear_scheduled_hook( $hook ) |
移除該鉤子所有排程任務(含循環與單次) |
wp_reschedule_event |
wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) |
重新排程(官方文檔稀缺,實際建議先 unschedule 再 schedule) |
$timestamp (int, 必填):首次執行時間戳,**必須使用 current_time('timestamp') 而非 time()**,以兼容時區設置。$recurrence (string, 必填):頻率標識,預設 'hourly'(3600s)、'twicedaily'(43200s)、'daily'(86400s)。$hook (string, 必填):Action Hook 名稱,到期時觸發 do_action($hook, $args)。$args (array, 可選):傳遞給鉤子回調函數的參數陣列。// 在插件啟用或主題設置中調用
if ( ! wp_next_scheduled( 'my_daily_cleanup' ) ) {
wp_schedule_event( current_time( 'timestamp' ), 'daily', 'my_daily_cleanup' );
}
// 掛載實際執行邏輯
add_action( 'my_daily_cleanup', 'my_cleanup_callback' );
function my_cleanup_callback() {
// 具體業務邏輯:清理過期暫存、發送報表等
error_log( 'Daily cleanup executed at ' . current_time( 'mysql' ) );
}
透過 cron_schedules 過濾器添加任意頻率:
function my_custom_cron_schedules( $schedules ) {
$schedules['weekly'] = array(
'interval' => 604800, // 7 * 24 * 60 * 60
'display' => __( '每週一次' )
);
$schedules['monthly'] = array(
'interval' => 2592000, // 30 * 24 * 60 * 60
'display' => __( '每月一次' )
);
$schedules['quarterly'] = array(
'interval' => 7776000, // 90 * 24 * 60 * 60
'display' => __( '每季一次' )
);
return $schedules;
}
add_filter( 'cron_schedules', 'my_custom_cron_schedules' );
註冊後即可像內建頻率一樣使用:
wp_schedule_event( current_time('timestamp'), 'weekly', 'my_weekly_report' );
https://your-site.com/wp-cron.php?doing_wp_cron
瀏覽器訪問即可強制執行,開發調試必備。
// wp-config.php define( 'DISABLE_WP_CRON', true );
# 系統 crontab (每分鐘檢查一次) * * * * * wget -q -O - "https://your-site.com/wp-cron.php?doing_wp_cron" >/dev/null 2>&1
安裝 WP Crontrol 外掛,後台直觀查看/編輯/運行任務。
add_action( 'my_task_hook', function() {
$log = 'Task ran at ' . current_time('mysql') . PHP_EOL;
file_put_contents( WP_CONTENT_DIR . '/cron-debug.log', $log, FILE_APPEND );
// 實際業務邏輯...
});
| 問題 | 原因 | 解決 |
|---|---|---|
| 任務不執行 | 網站長時間無訪問 | 配置系統 Cron 定時請求 wp-cron.php |
| 任務重複執行 | 註冊邏輯未判斷 wp_next_scheduled | 統一使用 if(!wp_next_scheduled()) 模式 |
| 時間偏差大 | 低流量 + 偽 Cron | 禁用偽 Cron + 系統 Cron |
| 自定義頻率不生效 | add_filter 註冊時機晚於任務註冊 | 確保 cron_schedules 過濾器在 plugins_loaded 前掛載 |
| 參數傳遞失效 | $args 序列化存儲,資源類型不可序列化 | 僅傳遞純量/陣列,避免對象/資源/閉包 |
掌握 WP-Cron 完整體系,即可構建可靠、可觀測、可擴展的 WordPress 定時任務架構。