
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 這類外掛新增:
// 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 個修訂版本)。
加上程式碼後:
- 打開一次網站,排程就排好了,頻率是每天,第一次在一小時後。
- 把排程時間改成「已經到了」,請求一次
wp-cron.php,模擬有訪客來觸發排程。 - 結果:40 天前的 3 則垃圾留言刪掉了,最近的 2 則留著;正常留言、垃圾桶的留言都沒動;修訂版本剩下最新的 5 個(第 8 到第 4 版);下一次排在 24 小時後。
WP-Cron 不是真的「每天準時」
WP-Cron 和主機上的排程不一樣:它要有人來看網站才會執行。訪客打開網頁時,WordPress 順便檢查有沒有到期的工作,有就去做。
- 流量大的網站,幾乎都會準時執行。
- 流量很少的網站,可能隔好幾天才跑一次。清理資料晚一點沒關係,但排程發佈文章、寄電子報就會延誤。
流量少、或排程很重要的網站,建議改用主機的排程:
- 在
wp-config.php加上這行,訪客開網頁時不再順便執行排程:
define( 'DISABLE_WP_CRON', true );- 到主機控制台(cPanel、HestiaCP、Plesk 都有「排程工作」或 Cron Jobs)新增一個每 15 分鐘執行一次的工作:
*/15 * * * * wget -q -O /dev/null "https://你的網址/wp-cron.php?doing_wp_cron"這樣不管有沒有人來,排程都會準時檢查。
想看排了哪些工作
WordPress 後台沒有內建排程列表,可以裝 WP Crontrol 外掛,它會在「工具」選單底下加一頁排程列表,看得到所有排程和下次執行時間,也能手動立刻執行一次。檢查完不需要的話可以再停用。
拿掉程式碼時,記得取消排程
把程式碼刪掉,排好的 zw_daily_cleanup 還會留在排程裡,每天到時間就執行一次「什麼都沒做」的空工作。不會造成問題,但不乾淨。刪程式碼之前,先換成這一行執行一次,再整段刪掉:
wp_clear_scheduled_hook( 'zw_daily_cleanup' );或用 WP Crontrol 直接刪掉這個排程。
先備份,再改天數
刪除是永久的,垃圾桶裡也找不回來。加上程式碼之前,先確定網站有備份。天數、要留幾個修訂版本,依網站需求調整:
- 會回頭看舊版本的文章(例如價目表、條款),修訂版本可以留多一點,例如 10 個。
- 也可以在
wp-config.php加define( 'WP_POST_REVISIONS', 5 );,從源頭限制每篇文章最多存 5 個修訂版本;已經存在的舊版本,還是要靠上面的排程清掉。
延伸閱讀
- WordPress 網站加速完整攻略:測速、主機、快取、圖片、外掛與資料庫清理
- WordPress 防垃圾留言總整理:外掛、留言設定、蜜罐與字數限制
- WordPress 自動更新怎麼設定?控制核心、外掛、佈景主題更新
資料庫清得乾淨,網站備份、搬家都比較快。正威網路行銷是 25 年經驗的基隆網頁設計工作室,網站管家年費包含系統更新與每日備份,台北與全台客戶也歡迎來聊聊。







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