Action 和 Filter 還在傻傻分不清楚?資深工程師帶你秒懂 WordPress Hooks 的任督二脈!

2025/12/2 | WP 開發技巧, 技術教學資源

WordPress Hooks:Action 與 Filter 秒懂攻略

厭倦了只會複製貼上程式碼,卻無法深入客製化網站?真正的 WordPress 開發者都懂得駕馭其核心架構:Hooks!資深工程師 Eric 為您揭秘 Action 與 Filter 這兩大關鍵機制:Action 負責在特定時間點「執行」任務,不需回傳值;Filter 則擔任資料的「攔截與修改」,且必須回傳值。搞懂它們的數據流與核心目的,你的 WordPress 開發功力將瞬間打通任督二脈,從「外掛安裝工」晉升為真正的架構師。別再猶豫,現在就動手實踐 Hooks 讓你的網站更具彈性!若有更複雜的企業級客製化需求,歡迎聯繫浪花科技,讓我們為您的專案賦能,打造高效穩定的數位解決方案!

需要專業協助?

聯絡浪花專案團隊 →

Action 和 Filter 還在傻傻分不清楚?資深工程師帶你秒懂 WordPress Hooks 的任督二脈!

嗨,我是浪花科技的資深工程師 Eric。在 WordPress 的世界裡打滾這麼多年,看過太多開發者(或自稱開發者的人)在客製化功能時,總是在 `functions.php` 裡複製貼上一堆看不懂的程式碼。能動就好,是吧?但當網站一出錯,或是想做更進階的修改時,就只能雙手一攤,開始懷疑人生。

今天,我得來跟你囉嗦一下 WordPress 開發的基石,也是區分「外掛安裝工」與「真正開發者」的關鍵分水嶺——那就是 WordPress Hooks。特別是裡面最常讓人搞混的兩兄弟:`Action Hook` 和 `Filter Hook`。搞懂它們的差異與應用,你的 WordPress 開發功力絕對能瞬間打通任督二脈,從此海闊天空。

WordPress Hooks 的核心精神:一切皆是「事件驅動」

在我們深入探討 Action 和 Filter 的差異之前,你必須先理解 WordPress 的運作哲學。你可以把 WordPress 想像成一條精密的工廠生產線,從接收請求到最終輸出一個完整的網頁,中間會經過數百個固定的「工作站」。

例如:

  • 「準備初始化」工作站 (`init`)
  • 「準備輸出網頁頭部」工作站 (`wp_head`)
  • 「準備儲存一篇文章」工作站 (`save_post`)
  • 「準備顯示文章內容」工作站 (`the_content`)

這些「工作站」就是所謂的 Hook(掛鉤)。WordPress 核心團隊非常聰明地在這些關鍵節點放了鉤子,讓我們開發者可以在不修改核心程式碼的前提下,把自己寫的功能「掛」上去。這就是所謂的「事件驅動(Event-Driven)」架構,也是 WordPress 能擁有如此龐大生態系的核心秘密。而 `Action` 和 `Filter` 就是我們用來掛上功能的兩種主要工具。

`add_action`:在特定時間點「執行」任務的命令官

先來說說 `Action Hook`。你可以把它想像成一個「廣播系統」。當生產線走到某個工作站時,它會對外大喊一聲:「嘿!我現在要載入頁首囉!」或「注意!這篇文章要發佈囉!」。

而我們使用 `add_action()`,就是在跟 WordPress 說:「聽到那個『發佈文章』的廣播時,麻煩幫我執行一下我指定的這段程式碼。」

`add_action` 是什麼?

簡單來說,`Action` 的核心精神是「執行(Do)」。它在特定的時間點觸發一個或多個函式,用來完成某項任務,例如:

  • 載入 CSS 或 JavaScript 檔案。
  • 在文章儲存後,發送一封 Email 通知。
  • 當使用者登入時,在資料庫裡記錄一筆 Log。

最重要的一點:Action 執行完就沒事了,它不關心結果,也不需要回傳任何東西給 WordPress。就像你交代秘書去寄信,你只關心「寄信」這個動作有沒有被執行,而不是要他回報信的內容是什麼。

`add_action` 語法與參數解析

它的基本語法長這樣:

add_action( 'hook_name', 'your_callback_function', $priority, $accepted_args );
  • `hook_name`:你要掛上的那個鉤子名稱,例如 `wp_enqueue_scripts`。
  • `your_callback_function`:聽到廣播後要執行的函式名稱。
  • `$priority`:(選填)優先級,數字越小越先執行,預設是 10。
  • `$accepted_args`:(選填)你的函式準備接收多少個參數,預設是 1。

實戰範例:在網站前台載入自訂的 CSS 樣式

這大概是每個主題開發者最常用的 Action 了。我們要在 `wp_enqueue_scripts` 這個鉤子上,掛上一個載入 CSS 的函式。

<?php
// 在 functions.php 中加入

function roamer_enqueue_custom_styles() {
    // 註冊並載入我們的 CSS 檔案
    wp_enqueue_style(
        'roamer-custom-style',
        get_stylesheet_directory_uri() . '/css/custom.css',
        [],
        '1.0.0'
    );
}

// 將我們的函式掛到 wp_enqueue_scripts 這個 Action Hook 上
add_action( 'wp_enqueue_scripts', 'roamer_enqueue_custom_styles' );
?>

你看,`roamer_enqueue_custom_styles` 這個函式只負責執行 `wp_enqueue_style`,它不需要 `return` 任何東西。

`add_filter`:在資料傳遞中「修改」內容的攔截手

如果說 Action 是廣播系統,那 `Filter Hook` 就是「品管員」。當生產線上的某個零件(資料)要傳到下一個工作站前,品管員會把它攔截下來,檢查一下,甚至動手修改一番,然後再把它放行,交給下一個流程。

`add_filter` 是什麼?

`Filter` 的核心精神是「修改(Modify)」。它接收一個值(例如文章標題字串),對它進行處理,然後 **必須** 把處理後的值回傳出去。

應用場景包括:

  • 在文章標題前加上「最新消息:」的前綴。
  • 修改文章摘要的預設長度。
  • 把文章內容中的特定關鍵字自動加上超連結。

這裡畫個大重點,也是新手最常犯的錯:Filter 的函式如果沒有 `return` 一個值,那原本的資料就會變成 `null`(空),你的網站內容可能就直接消失了! 這就像品管員把零件攔下來,結果忘了放回去,生產線就斷了。

`add_filter` 語法與參數解析

語法跟 `add_action` 幾乎一樣:

add_filter( 'hook_name', 'your_callback_function', $priority, $accepted_args );

唯一的差別在於,你傳入的 `your_callback_function` 的第一個參數通常就是準備要被修改的資料,而且函式最後一定要 `return` 這個(或修改後的)資料。

實戰範例:修改文章摘要(Excerpt)的預設字數

WordPress 預設的文章摘要長度是 55 個字,如果我們想改成 20 個字,就可以用 `excerpt_length` 這個 Filter Hook。

<?php
// 在 functions.php 中加入

function roamer_custom_excerpt_length( $length ) {
    // 把原本的 $length (預設是 55) 改成 20
    return 20;
}

// 將我們的函式掛到 excerpt_length 這個 Filter Hook 上
add_filter( 'excerpt_length', 'roamer_custom_excerpt_length', 999 );
?>

看到 `return 20;` 了嗎?我們把傳進來的 `$length` 變數直接忽略,強行回傳 20。WordPress 收到這個回傳值後,就會用 20 作為新的摘要長度。

終極對決:`add_action` vs. `add_filter` 一次看懂

說了這麼多,我幫你整理一下,讓你徹底告別混亂:

  • 核心目的:
    • `add_action`:執行一個動作 (Do something)。
    • `add_filter`:修改一個數值 (Modify something)。
  • 回傳值:
    • `add_action` 的回呼函式不需要 `return`。
    • `add_filter` 的回呼函式必須 `return` 一個值,否則會出大事。
  • 數據流:
    • `add_action` 是單向的,觸發了就結束了,像個開關。
    • `add_filter` 是雙向的,它會攔截數據流,處理後再放行,像個閥門。
  • 問自己一個問題:
    • 「我想要在『某個時間點』一件事嗎?」 -> 用 `Action`。
    • 「我想要在『某個資料被使用前』它的內容嗎?」 -> 用 `Filter`。

進階實戰:當 Action 遇上 Filter 的協奏曲

真正的開發場景中,Action 和 Filter 常常需要攜手合作。讓我們來看一個更真實的例子:

情境: 我們希望在文章儲存時(Action),檢查文章內容。如果內容中包含了「機密」這個關鍵字,我們就在標題前自動加上「[內部文件]」的前綴(Filter)。

這個需求完美地展現了兩者的協同作戰:

  1. 我們需要監聽「文章儲存」這個事件 -> 使用 `save_post` 這個 `Action Hook`。
  2. 在事件觸發後,我們需要修改文章的標題 -> 這顯然是 `Filter` 的工作,但 `save_post` 是一個 Action,它不處理標題。怎麼辦?我們可以在 `save_post` 觸發的函式裡,動態地去修改文章資料本身。
<?php
// 在 functions.php 中加入

function roamer_check_post_content_on_save( $post_id, $post, $update ) {
    // 如果是自動草稿或修訂版本,則不處理
    if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) {
        return;
    }

    // 檢查文章內容是否包含 '機密'
    if ( strpos( $post->post_content, '機密' ) !== false ) {

        // 檢查標題是否已經有前綴,避免重複添加
        if ( strpos( $post->post_title, '[內部文件]' ) === false ) {
            // 建立要更新的文章資料陣列
            $updated_post = array(
                'ID'         => $post_id,
                'post_title' => '[內部文件] ' . $post->post_title,
            );

            // 因為我們在 save_post 這個 hook 裡,如果直接用 wp_update_post 會造成無限迴圈
            // 所以要先移除我們自己的 hook,更新完再加回來
            remove_action( 'save_post', 'roamer_check_post_content_on_save', 10, 3 );
            wp_update_post( $updated_post );
            add_action( 'save_post', 'roamer_check_post_content_on_save', 10, 3 );
        }
    }
}

// 我們將函式掛在 save_post 這個 Action 上
// 注意!我們需要傳入 3 個參數,所以最後一個數字是 3
add_action( 'save_post', 'roamer_check_post_content_on_save', 10, 3 );
?>

這個範例稍微複雜,但完美詮釋了「在一個動作(Action)中,去觸發一個資料的修改(Modification)」的過程。這就是進階開發的日常。

總結:別再害怕,動手去玩吧!

恭喜你!如果你能耐心看到這裡,代表你已經超越了 80% 的 WordPress 使用者。`Action` 和 `Filter` 是 WordPress 賦予開發者最大的自由,也是所有外掛和主題的靈魂所在。

一開始可能會覺得抽象,但最好的學習方式就是「動手做」。試著去修改看看你的文章標題、在頁尾加上一段文字、或是在使用者登出時做點什麼。當你成功掛上第一個 Hook,並看到它如預期般運作時,那種成就感,就是身為一個工程師最大的樂趣。

希望這篇有點囉嗦的文章能幫助你打通對 WordPress Hooks 的理解。不要再把 `functions.php` 當成神秘的黑盒子,把它變成你揮灑創意的畫布吧!


相關閱讀

如果你在 WordPress 開發上遇到了更複雜的挑戰,或是有企業級的客製化需求,單靠理解 Hooks 可能還不夠。浪花科技專注於打造高效、穩定且可擴展的 WordPress 解決方案。歡迎點擊這裡,填寫表單聯繫我們,讓我們的專業團隊為你的專案賦能!

常見問題 (FAQ)

Q1: Action 和 Filter 最根本的差別是什麼?

最根本的差別在於「回傳值」。Action Hook 用來在特定時間點「執行」一個動作,它的回呼函式不需要回傳任何東西。而 Filter Hook 則是用來「修改」傳遞中的資料,它的回呼函式「必須」回傳一個值(修改後或原始的值),否則會中斷資料流,導致網站內容空白或出錯。

Q2: 如果我的 Filter function 忘了 `return` 值會怎麼樣?

這是新手最常犯的致命錯誤!如果你的 Filter 函式沒有回傳值,那麼傳遞到這個 Filter 的資料就會變成 `null`(空值)。舉例來說,如果是在 `the_content` 這個 filter 上忘了回傳,你的所有文章內容都會直接消失不見,變成一片空白。所以,寫 Filter 時請務必再三確認函式最後有 `return`。

Q3: 我怎麼知道 WordPress 裡面有哪些 Hook 可以用?

有幾個好方法:
1. 官方文件: 查詢 WordPress Developer Resources 的 Hook 參考,這是最權威的來源。
2. 使用外掛: 安裝像 Query Monitor 這樣的開發者工具,它可以顯示當前頁面載入了哪些 Hooks。
3. 直接看原始碼: 這是最硬核但最有效的方法。直接在 WordPress 核心、主題或外掛的程式碼中搜尋 `do_action()`(代表這是一個 Action Hook)和 `apply_filters()`(代表這是一個 Filter Hook)。

Q4: 什麼是 Hook 的優先權 (Priority)?

優先權(Priority)是 `add_action()` 和 `add_filter()` 的第三個參數,它是一個數字,用來決定掛在同一個 Hook 上的多個函式的執行順序。數字越小,代表越優先執行。預設值是 10。如果你希望你的函式比其他函式更早或更晚執行,就可以調整這個數字。

 
立即諮詢,索取免費1年網站保固