Action 還是 Filter?WordPress Hooks 終極二選一難題,資深工程師帶你走出選擇困難!
嗨,我是浪花科技的資深工程師 Eric。寫程式這麼多年,我看過無數剛踏入 WordPress 開發世界的新手(甚至是老手),在一個看似簡單卻至關重要的十字路口上徘徊不定:我現在這個功能,到底該用 add_action 還是 add_filter?
這問題就像問工程師,Vim 跟 Emacs 哪個好一樣,雖然沒那麼引戰,但選錯了,輕則功能不如預期,重則網站效能低落、甚至出現難以追蹤的 Bug。很多人都聽過最簡單的解釋:「Action 是『做事』,Filter 是『改東西』」。這句話沒錯,但太簡化了。現實世界的開發場景遠比這複雜,魔鬼都藏在細節裡。今天,就讓我這個老司機帶你深入 WordPress Hooks 的核心,徹底搞懂 Action 與 Filter 的差異與應用,讓你從此告別選擇困難!
鉤子 (Hooks) 的核心思想:WordPress 的彈性靈魂
在我們深入探討 Action 和 Filter 的對決之前,得先花點時間聊聊「鉤子 (Hooks)」這個概念。身為一個工程師,我得說,Hooks 絕對是 WordPress 架構中最天才的設計之一。它賦予了 WordPress 無與倫比的彈性,讓我們這些開發者可以在不修改核心程式碼的前提下,對 WordPress 的功能進行天馬行空的擴充與客製化。
你可以把整個 WordPress 的執行流程想像成一條高速運轉的生產線。這條生產線在各個關鍵節點,比如「準備顯示文章標題前」、「使用者成功登入後」、「準備載入頁尾腳本時」,都預先埋設了很多「插座」。這些插座就是所謂的「鉤子」。
- Action Hooks:就像是生產線上的「警報器插座」。當流程走到這個節點,它會大喊一聲:「嘿!現在要執行『某某動作』了!」任何接上這個插座的裝置(也就是你的函式)都會被觸發執行。例如,在頁尾 (`wp_footer`) 這個節點,你可以掛載一個函式來插入 Google Analytics 追蹤碼。
- Filter Hooks:這更像是生產線上的「品質檢驗站」。當一個零件(資料)流經這個站點時,它會被攔下來,交給你掛載的函式進行「加工」。你可以檢查它、修改它、甚至替換它,但最重要的是,加工完畢後,你「必須」把這個零件放回生產線,讓流程繼續下去。例如,你可以攔截文章標題 (`the_title`),在它前面加上「最新消息:」的字樣。
理解了這個核心思想,你就會明白為什麼我們總是強調「千萬不要去改 WordPress 核心檔案」。透過 Hooks,我們就能用更優雅、更安全、也更具可維護性的方式來完成任務。
Action vs. Filter:不只是「做事」與「改東西」這麼簡單
好了,理論課上完了,接下來進入實戰。讓我們用具體的程式碼和場景來剖析這兩兄弟的異同。
h3>Action Hooks: 在特定時間點「執行」一段程式碼
Action 的核心精神是「Fire and Forget」(觸發後不理)。它在特定的時間點被觸發,執行你指定的函式,然後就沒它的事了。它不關心你的函式做了什麼,也不期望你回傳任何東西給它。
使用場景:
- 在頁首或頁尾插入追蹤碼、CSS 或 JavaScript。
- 當一篇文章發佈時,自動發送通知 Email 給作者。
- 當使用者註冊成功後,將他的資料同步到外部的 CRM 系統。
- 清除特定快取。
範例:在網站頁尾加入自訂 JavaScript
假設我們想在每個頁面的 `</body>` 標籤前,加入一段自訂的 JavaScript 程式碼。最適合的 Action Hook 就是 `wp_footer`。
<?php
// 將這段程式碼加入你的主題 functions.php 或自訂外掛中
function roamer_add_custom_footer_script() {
echo '<script>console.log("Hello from Roamer Tech!");</script>';
}
add_action('wp_footer', 'roamer_add_custom_footer_script');
?>
你看,`roamer_add_custom_footer_script` 這個函式只是單純地 `echo` 出一段 script,它沒有回傳任何值。這就是一個標準的 Action 應用。
h3>Filter Hooks: 「過濾」並「回傳」修改後的資料
Filter 的核心則是「Take, Modify, Return」(接收、修改、回傳)。它會接收一個或多個參數(通常是第一個參數為要被過濾的資料),讓你的函式進行處理,然後它「必須」接收你回傳的值,並用這個新值取代舊值,繼續接下來的流程。
工程師的小囉嗦:我必須用粗體再強調一次,**Filter 的函式一定要有 `return`**!這是我看過新手最常犯的錯誤之一。如果你忘記 `return`,傳進來的值就會變成 `NULL`,通常會導致網站內容消失或直接白畫面。除錯時,請務必先檢查你的 Filter 函式最後有沒有乖乖 `return`。
使用場景:
- 修改文章標題、內文或摘要的顯示方式。
- 變更 WooCommerce 產品的價格。
- 自訂「閱讀更多」的連結文字。
- 在使用者個人資料頁面新增或移除欄位。
範例:將所有文章標題都加上前綴
假設我們希望網站上所有文章的標題前面,都自動加上「[精選文章] 」的字樣。這時候 `the_title` 這個 Filter Hook 就是你的好朋友。
<?php
// 將這段程式碼加入你的主題 functions.php 或自訂外掛中
function roamer_add_title_prefix($title, $id = null) {
// 我們只在主循環的文章中修改,避免影響到選單、小工具等地方的標題
if (is_singular() && in_the_loop() && is_main_query()) {
return '[精選文章] ' . $title;
}
// 如果不符合條件,務必回傳原始的標題!
return $title;
}
add_filter('the_title', 'roamer_add_title_prefix', 10, 2);
?>
在這個範例中,我們的函式接收了 `$title`,經過條件判斷後,回傳了加工後的新標題,或者在不符條件時回傳原始標題。這就是 Filter 的標準作業流程。
決策的十字路口:我到底該用 Action 還是 Filter?
現在你已經了解兩者的運作原理,讓我們建立一個簡單的決策流程,幫助你在開發時快速做出正確選擇。
當你有一個需求時,先問自己第一個問題:
「我的主要目的是要『改變』WordPress 執行流程中傳遞的某個特定資料(字串、陣列、物件等)嗎?」
- 是:恭喜你,99% 的情況下你應該使用 Filter。例如:改變文章內容、修改圖片 class、調整查詢參數等。
- 否:接著問自己第二個問題:「我的主要目的是在某個時間點,『觸發』一個獨立的動作(例如:寫入資料庫、呼叫外部 API、輸出 HTML)而不需要把結果交還給當前的流程嗎?」
- 是:那毫無疑問,你應該使用 Action。
- 否:那可能需要重新思考你的需求邏輯了。是不是把一個複雜的功能混在一起了?試著把它拆解成更小的步驟,再用這個流程判斷一次。
工程師的碎碎念:一個常見的誤區
這裡有一個我常看到的反模式:用 Filter 來做 Action 的事情。例如,有人可能會這樣寫:
<?php
// 錯誤示範!不要這樣做!
add_filter('the_title', function($title) {
// 在 filter 裡面做與資料修改無關的事情
error_log('這篇文章被瀏覽了:' . $title);
return $title;
});
?>
雖然這段程式碼能跑,但這是非常糟糕的設計。`the_title` 這個 filter 在一個頁面載入的過程中可能會被呼叫數十次(標題、瀏覽器頁籤、導覽麵包屑…),你的 `error_log` 就會被瘋狂觸發,造成不必要的效能浪費和混亂的日誌。正確的做法應該是找一個更適合的 Action,例如 `wp_head` 或 `loop_start` 來執行這個紀錄行為,而且只執行一次。
進階應用:打造可擴充的程式碼
當你掌握了 Action 和 Filter,下一步就是學會建立自己的 Hooks,讓你的外掛或主題也擁有像 WordPress 核心一樣的擴充能力。
- `do_action(‘my_custom_action’, $arg1, $arg2);`:在你的程式碼中建立一個 Action 鉤子。
- `apply_filters(‘my_custom_filter’, $data_to_filter, $arg1);`:建立一個 Filter 鉤子。
當你開發一個複雜的外掛時,在關鍵流程中埋設你自己的 Hooks,可以讓其他開發者(甚至是未來的你)更容易地去擴充與客製化你的外掛功能,而不需要去修改你的外掛原始碼。這是一個專業 WordPress 開發者必備的思維。
總結來說,Action 和 Filter 是 WordPress 開發的基石。搞懂它們的差異,並在對的場景使用對的工具,是寫出乾淨、高效、可維護程式碼的第一步。別再只是模糊地用「做事」和「改東西」來區分了,深入理解它們的運作哲學,你的 WordPress 開發功力將會提升到一個全新的層次。
希望這篇文章能幫你解開長久以來的疑惑。如果你在 WordPress 開發上遇到了更複雜的架構問題,或是需要打造高度客製化的企業級網站,浪花科技的團隊擁有豐富的實戰經驗。
歡迎點擊這裡,填寫表單與我們聯繫,讓我們用專業的技術,為您的事業打造穩固的數位基礎!
延伸閱讀
- WordPress 開發的任督二脈:搞懂 Action & Filter Hooks,客製化功力大爆發!
- 解鎖 WordPress 的隱藏力量:functions.php 終極實戰指南,讓你的網站秒變客製化神器!
- 別讓你的網站等到天荒地老!WordPress Transients API 終極指南,一招榨乾網站潛在效能
常見問題 (FAQ)
Q1: Action Hook 和 Filter Hook 最直觀的差別是什麼?
最直觀的差別在於「目的」與「回傳值」。Action 的目的是在特定時間點「執行一個動作」,它不需要回傳任何東西。Filter 的目的是「過濾並修改資料」,它必須接收一個值,處理後再把這個值(或新值)回傳出去,讓 WordPress 繼續後續流程。你可以想像 Action 是事件通知,而 Filter 是品質控管。
Q2: 我可以在 Action 函式裡面修改資料嗎?
可以,但你修改的通常是全域變數、資料庫中的資料,或是透過物件的引用來修改。你並不是在修改 WordPress 當前流程中「傳遞」的那個資料。如果你的目的是要改變某個即將要被顯示或使用的變數內容(例如文章標題),那麼使用 Filter 才是正確且標準的做法。
Q3: 我忘了在 Filter 函式裡加上 `return` 會發生什麼事?
這是一個非常常見且會導致嚴重問題的錯誤!如果你的 Filter 函式沒有明確 `return` 一個值,PHP 會預設回傳 `NULL`。這會導致原本應該被過濾的資料(例如文章內容、標題字串)直接變成空的,最終可能造成頁面顯示異常、內容消失,甚至是 PHP 錯誤導致的「死亡白畫面」。所以,寫 Filter 時請務必再三檢查,確保每個邏輯分支都有回傳值。






