
在 WordPress 刪除一篇文章,文章用到的圖片並不會跟著刪掉:媒體庫裡的圖片、WordPress 自動產生的各種尺寸縮圖,都還留在主機上。文章刪多了,主機空間就被這些用不到的檔案佔掉。
這篇提供一段程式碼,在永久刪除文章時,把「只有這篇文章在用」的圖片一起刪除。重點在於不能誤刪:同一張圖片可能也是別篇文章的特色圖片,或出現在別篇文章的內文裡,刪掉就會變成破圖。
動手之前:一定要先備份
媒體檔案刪除之後,WordPress 沒有垃圾桶可以救回來。使用這段程式碼之前:
- 備份資料庫與
wp-content/uploads資料夾(用主機的備份功能或備份外掛都可以)。 - 有測試站的話,先在測試站試過,再放到正式網站。
先了解:刪除文章時,WordPress 會做什麼?
- 移到垃圾桶:什麼都不會刪,文章隨時可以還原。
- 永久刪除(在垃圾桶按「永久刪除」或「清空垃圾桶」,或是文章在垃圾桶放超過 30 天被自動清除):文章本身、自訂欄位、修訂版本會被刪掉,但圖片會留在媒體庫,變成「未附加」的狀態。
下面的程式碼掛在 before_delete_post 這個動作(action)上,只有永久刪除時才會執行,移到垃圾桶不受影響。
程式碼
加到子主題的 functions.php,或用 Code Snippets 外掛新增:
/**
* 永久刪除文章時,一併刪除只屬於這篇文章的圖片
* 被其他文章當特色圖片、或出現在其他文章內文裡的圖片會保留
*/
add_action( 'before_delete_post', 'ahwei_delete_post_images' );
function ahwei_delete_post_images( $post_id ) {
$post = get_post( $post_id );
// 只處理一般文章;要包含頁面可改成 array( 'post', 'page' )
if ( ! $post || ! in_array( $post->post_type, array( 'post' ), true ) ) {
return;
}
// 自動草稿不處理
if ( 'auto-draft' === $post->post_status ) {
return;
}
// 候選圖片:特色圖片 + 在這篇文章上傳的圖片
$candidates = array();
$thumbnail_id = (int) get_post_thumbnail_id( $post );
if ( $thumbnail_id ) {
$candidates[] = $thumbnail_id;
}
$attached = get_posts( array(
'post_type' => 'attachment',
'post_status' => 'inherit',
'post_parent' => $post_id,
'post_mime_type' => 'image',
'posts_per_page' => -1,
'fields' => 'ids',
) );
$candidates = array_unique( array_merge( $candidates, array_map( 'intval', $attached ) ) );
foreach ( $candidates as $attachment_id ) {
if ( ! ahwei_is_image_used_elsewhere( $attachment_id, $post_id ) ) {
wp_delete_attachment( $attachment_id, true );
}
}
}
/**
* 檢查圖片有沒有被其他文章使用 (特色圖片或內文)
*/
function ahwei_is_image_used_elsewhere( $attachment_id, $post_id ) {
global $wpdb;
// 1) 是不是其他文章的特色圖片
$as_thumbnail = (int) $wpdb->get_var( $wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->postmeta} pm
INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id
WHERE pm.meta_key = '_thumbnail_id'
AND pm.meta_value = %s
AND pm.post_id <> %d
AND p.post_type <> 'revision'",
(string) $attachment_id,
$post_id
) );
if ( $as_thumbnail > 0 ) {
return true;
}
// 2) 其他文章的內文有沒有用到 (比對 wp-image-編號 與檔案路徑)
$patterns = array( '%' . $wpdb->esc_like( 'wp-image-' . $attachment_id ) . '%' );
$file = (string) get_post_meta( $attachment_id, '_wp_attached_file', true );
if ( '' !== $file ) {
// 例如 2024/05/photo-scaled.jpg 取出 2024/05/photo
$base = preg_replace( '/(-scaled)?\.[a-z0-9]+$/i', '', $file );
$patterns[] = '%' . $wpdb->esc_like( $base ) . '%';
}
foreach ( $patterns as $like ) {
$in_content = (int) $wpdb->get_var( $wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->posts}
WHERE ID <> %d
AND post_type NOT IN ( 'revision', 'attachment' )
AND post_content LIKE %s",
$post_id,
$like
) );
if ( $in_content > 0 ) {
return true;
}
}
return false;
}這段程式碼做的事:
- 只處理一般文章(
post),自動草稿不處理。想連頁面一起處理,把array( 'post' )改成array( 'post', 'page' )。 - 找出候選圖片:這篇文章的特色圖片,以及在這篇文章裡上傳的圖片。
- 每一張都先檢查:有沒有被其他文章設成特色圖片?其他文章、頁面的內文有沒有用到?只要有,就保留。
- 確定沒被使用的,才用 WordPress 內建的
wp_delete_attachment()刪除,它會把原圖和所有尺寸的縮圖一起刪掉。
內文的比對是用圖片的 wp-image-編號 與檔案路徑去找,原則是「寧可多保留、不要誤刪」,所以偶爾會有其實沒被使用、卻被保留下來的圖片,這是刻意的設計。一次清空大量文章時,因為每張圖片都要檢查,可能會比平常久一點。
這段程式碼判斷不到的地方
程式只檢查特色圖片與文章內文,下面這些地方用到的圖片它看不到,可能被誤刪:
- 頁面編輯器(Elementor、Divi 等)存在自己欄位裡的圖片
- 小工具、選單、主題設定裡的圖片(例如 Logo、背景圖)
- WooCommerce 商品圖庫
- 傳統編輯器用
[gallery ids="..."]短代碼插入的相簿(只記錄圖片編號,沒有圖片網址) - 其他網站或社群貼文直接引用你的圖片網址
網站有用到上面這些,建議不要使用自動刪除,改用下面的手動清理方式。
比較保守的做法:定期手動清理
- 到「媒體 → 媒體庫」,切換成清單檢視。
- 用上方的篩選選單選「未附加」,列出沒有附加在任何文章上的檔案。
- 逐一確認真的沒在使用,再刪除。
要注意「未附加」不代表沒被使用,同一張圖片可能被插入到別篇文章裡,所以刪除前還是要確認。也有外掛可以掃描整個網站的圖片使用狀況,不管用哪一種工具,刪除前都一樣要先備份。
舊版程式碼為什麼不要用
- 引號變成了全形的“ ”與‘ ’:文章搬家時引號被轉換,照著貼上會造成 PHP 語法錯誤,網站直接白畫面。
- 不檢查圖片有沒有被其他文章使用:共用的特色圖片會被刪掉,其他文章跟著破圖。
- 每一種內容被刪除時都會執行:頁面、商品、其他外掛的自訂內容被刪除時,也會去刪圖片。
- 直接把變數組進 SQL 語法:應該用
$wpdb->prepare()處理;最後那段手動刪除自訂欄位的語法也是多餘的,WordPress 刪除文章時本來就會處理。
常見問題
把文章移到垃圾桶,圖片會被刪嗎?
不會。只有永久刪除時才會執行,文章在垃圾桶裡都還能連同圖片一起還原。但要記得,垃圾桶裡超過 30 天的文章會被 WordPress 自動永久刪除,那時候程式也會執行。
以前刪掉的文章,留下來的圖片怎麼辦?
這段程式碼只會處理之後刪除的文章。以前留下來的圖片,請用上面「定期手動清理」的方式處理。
延伸閱讀
- WordPress 媒體庫分類:不用外掛,用 register_taxonomy 替圖片加上獨立分類
- WordPress 限制上傳檔案類型:upload_mimes 寫法與 JPG、PNG、WebP、SVG 格式選擇
- WordPress functions.php 實用程式碼整理:10 個常用又安全的小技巧
主機空間被舊檔案塞滿、又不敢亂刪的時候,最需要有人幫忙把關。正威網路行銷是 25 年經驗的基隆網頁設計工作室,提供網站維護託管,也服務台北與全台客戶,歡迎來聊聊。







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