0%

正威網路行銷工作室,專注於基隆、台北與全台客製化網頁設計,提供專業 RWD 響應式、SEO 搜尋引擎優化、品牌形象設計與網站維護託管服務。

搜尋文章
聯絡資訊
地址基隆市仁二路 220 號 5 樓
追蹤我們

WordPress 排程自動清理垃圾留言和修訂版本:WP-Cron 寫法

WordPress 排程自動清理垃圾留言和修訂版本:WP-Cron 寫法 封面

WordPress 網站經營幾年,資料庫裡會累積很多用不到的東西:

  • 垃圾留言:被標成垃圾的留言不會自己消失,幾千則躺在資料庫裡。
  • 修訂版本:每按一次「更新」,WordPress 就把舊內容存一份。一篇改了 50 次的文章,就有 50 份副本。

手動清理很容易忘,這篇用 WordPress 內建的排程功能(WP-Cron),讓網站每天自己清一次,不用外掛。

WordPress 自己會清什麼、不會清什麼

先弄清楚,免得重複做:

  • 垃圾桶:文章、頁面、留言丟進垃圾桶,30 天後 WordPress 會自動永久刪除(天數由 EMPTY_TRASH_DAYS 決定)。
  • 垃圾留言:WordPress 本身不會自動刪除。我們看了 WordPress 7.1.3 的原始碼,負責清垃圾桶的程式遇到垃圾留言,只會清掉記錄時間的欄位,留言本身留著。
  • 有裝 Akismet:Akismet 預設會刪除 15 天前、由它判定的垃圾留言。沒裝 Akismet,或用其他防垃圾留言的方法,就要自己清。
  • 修訂版本:預設沒有上限,永遠不會自己刪。

程式碼

放在子佈景主題的 functions.php,或用 Code Snippets 這類外掛新增:

PHP
// 1. 排一個每天執行一次的工作(已經排過就不重複排)
add_action( 'init', function () {
	if ( ! wp_next_scheduled( 'zw_daily_cleanup' ) ) {
		wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'zw_daily_cleanup' );
	}
} );

// 2. 每天要做的事
add_action( 'zw_daily_cleanup', function () {
	// 垃圾留言:超過 30 天的永久刪除,一次最多 500 則
	$spam_ids = get_comments( array(
		'status'     => 'spam',
		'date_query' => array( array( 'before' => '30 days ago' ) ),
		'number'     => 500,
		'fields'     => 'ids',
	) );
	foreach ( $spam_ids as $comment_id ) {
		wp_delete_comment( $comment_id, true );
	}

	// 修訂版本:每篇文章只留最新的 5 個,一次最多處理 100 篇
	global $wpdb;
	$post_ids = $wpdb->get_col(
		"SELECT post_parent FROM {$wpdb->posts}
		 WHERE post_type = 'revision'
		 GROUP BY post_parent HAVING COUNT(*) > 5
		 LIMIT 100"
	);
	foreach ( $post_ids as $post_id ) {
		$revisions = wp_get_post_revisions( $post_id, array( 'check_enabled' => false ) ); // 新的在前面
		foreach ( array_slice( $revisions, 5 ) as $revision ) {
			wp_delete_post_revision( $revision );
		}
	}
} );

第一段:排程

  • wp_next_scheduled() 先查有沒有排過。WordPress 每次載入都會執行 init,不先查的話會一直重複排。
  • wp_schedule_event( 開始時間, 'daily', 工作名稱 ) 排一個每天執行的工作,第一次在一小時後。內建的頻率有 hourly(每小時)、twicedaily(每天兩次)、daily(每天)、weekly(每週)。

第二段:每天要做的事

  • 垃圾留言:用 get_comments() 找出狀態是「垃圾」、而且是 30 天前的留言,wp_delete_comment( 編號, true ) 永久刪除。留 30 天是讓你有時間檢查,萬一有正常留言被誤判,還救得回來。
  • 修訂版本:先找出修訂版本超過 5 個的文章,wp_get_post_revisions() 拿到這篇的所有修訂版本(新的排前面),從第 6 個開始用 wp_delete_post_revision() 刪掉。
  • check_enabled 設成 false:就算網站關掉了修訂版本功能,以前留下的舊修訂版本一樣會被清理。
  • 每次都有上限(500 則留言、100 篇文章)。累積很多的網站,第一次清理不會一次跑太久把網站卡住,剩下的明天繼續。

刪除都用 WordPress 的函式,不直接下 SQL 刪資料。這樣留言的附屬資料、修訂版本的相關紀錄會一起清乾淨,其他外掛也能收到「留言被刪除」的通知。

實際測試的結果

測試網站先準備好:5 則垃圾留言(其中 3 則是 40 天前的)、1 則 40 天前的正常留言、1 則在垃圾桶的留言、1 篇改過 8 次的文章(8 個修訂版本)。

加上程式碼後:

  1. 打開一次網站,排程就排好了,頻率是每天,第一次在一小時後。
  2. 把排程時間改成「已經到了」,請求一次 wp-cron.php,模擬有訪客來觸發排程。
  3. 結果:40 天前的 3 則垃圾留言刪掉了,最近的 2 則留著;正常留言、垃圾桶的留言都沒動;修訂版本剩下最新的 5 個(第 8 到第 4 版);下一次排在 24 小時後。

WP-Cron 不是真的「每天準時」

WP-Cron 和主機上的排程不一樣:它要有人來看網站才會執行。訪客打開網頁時,WordPress 順便檢查有沒有到期的工作,有就去做。

  • 流量大的網站,幾乎都會準時執行。
  • 流量很少的網站,可能隔好幾天才跑一次。清理資料晚一點沒關係,但排程發佈文章、寄電子報就會延誤。

流量少、或排程很重要的網站,建議改用主機的排程:

  1. 在 wp-config.php 加上這行,訪客開網頁時不再順便執行排程:
PHP
define( 'DISABLE_WP_CRON', true );
  1. 到主機控制台(cPanel、HestiaCP、Plesk 都有「排程工作」或 Cron Jobs)新增一個每 15 分鐘執行一次的工作:
Shell / 終端機
*/15 * * * * wget -q -O /dev/null "https://你的網址/wp-cron.php?doing_wp_cron"

這樣不管有沒有人來,排程都會準時檢查。

想看排了哪些工作

WordPress 後台沒有內建排程列表,可以裝 WP Crontrol 外掛,它會在「工具」選單底下加一頁排程列表,看得到所有排程和下次執行時間,也能手動立刻執行一次。檢查完不需要的話可以再停用。

拿掉程式碼時,記得取消排程

把程式碼刪掉,排好的 zw_daily_cleanup 還會留在排程裡,每天到時間就執行一次「什麼都沒做」的空工作。不會造成問題,但不乾淨。刪程式碼之前,先換成這一行執行一次,再整段刪掉:

PHP
wp_clear_scheduled_hook( 'zw_daily_cleanup' );

或用 WP Crontrol 直接刪掉這個排程。

先備份,再改天數

刪除是永久的,垃圾桶裡也找不回來。加上程式碼之前,先確定網站有備份。天數、要留幾個修訂版本,依網站需求調整:

  • 會回頭看舊版本的文章(例如價目表、條款),修訂版本可以留多一點,例如 10 個。
  • 也可以在 wp-config.php 加 define( 'WP_POST_REVISIONS', 5 );,從源頭限制每篇文章最多存 5 個修訂版本;已經存在的舊版本,還是要靠上面的排程清掉。

延伸閱讀

資料庫清得乾淨,網站備份、搬家都比較快。正威網路行銷是 25 年經驗的基隆網頁設計工作室,網站管家年費包含系統更新與每日備份,台北與全台客戶也歡迎來聊聊。

分享這篇文章

返回文章列表更多「Wordpress代碼教學」文章

發表留言

還沒有人留言,歡迎第一個分享你的想法或問題。留言經審核後才會顯示,Email 不會公開。

讓我們一起打造
您的專屬網站!