首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

WordPress 插件機制深度解析:從啟用到 Hook 執行的完整生命週期

     編輯:PHP 綜合知識

核心流程圖

plugins_loaded → muplugins_loaded → 載入啟用插件 → init → wp_loaded → 模板載入 → wp_head / wp_footer 等 Hook 觸發

1. 插件檔案標準頭部

<?php
/**
 * Plugin Name:       My Awesome Plugin
 * Plugin URI:        https://example.com/plugin
 * Description:       簡短說明,顯示於後台插件列表
 * Version:           1.0.0
 * Requires at least: 5.8
 * Requires PHP:      7.4
 * Author:            Your Name
 * Author URI:        https://example.com
 * License:           GPL v2 or later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:       my-awesome-plugin
 * Domain Path:       /languages
 */
  • WP 解析此區塊填充 wp_plugins 緩存,顯示於後台。
  • Text Domain 用於國際化 __('string', 'text-domain')。

2. 啟用流程:wp-settings.php 關鍵代碼

// 簡化版核心邏輯
if ( $active_plugins = get_option('active_plugins') ) {
    foreach ( $active_plugins as $plugin_file ) {
        // $plugin_file 形如 'my-plugin/my-plugin.php' (相對於 WP_PLUGIN_DIR)
        if ( validate_file($plugin_file) === 0 && file_exists(WP_PLUGIN_DIR . '/' . $plugin_file) ) {
            include_once WP_PLUGIN_DIR . '/' . $plugin_file;
        }
    }
}
  • active_plugins 選項存儲啟用插件的相對路徑陣列(單站點)或序列化陣列(多站點)。
  • mu-plugins (Must-Use) 目錄下檔案自動載入,無需啟用,優先於一般插件。
  • include_once 確保重複啟用不報錯,但也意味著插件主檔案只能定義函數/類/掛 Hook,不可直接輸出內容。

3. Hook 系統:Action vs Filter

類型函數用途回傳值
Actionadd_action() / do_action()在特定時間點執行副作用(寫 DB、送信、輸出 HTML)忽略
Filteradd_filter() / apply_filters()修改/過濾資料(標題、內容、查詢參數)必須回傳修改後的值

優先權與參數

// add_action( $hook, $callback, $priority = 10, $accepted_args = 1 )
add_action('wp_footer', 'my_output', 5, 0);      // 較早執行 (priority 5 < 10)
add_filter('the_content', 'my_modify', 10, 2);   // 接收 2 參數:$content, $post
  • 數字越小越早執行(Action);Filter 同理。
  • 同優先權按註冊順序執行。

4. 範例插件完整生命週期

<?php
// my-plugin.php
defined('ABSPATH') or die; // 防止直接存取

// 1. 早期初始化:載入文字域、定義常數
add_action('plugins_loaded', function() {
    load_plugin_textdomain('my-plugin', false, dirname(plugin_basename(__FILE__)) . '/languages');
    define('MY_PLUGIN_VERSION', '1.0.0');
});

// 2. 核心功能掛載:init 階段(當前用戶已確認、主題函數可用)
add_action('init', function() {
    // 註冊自訂文章類型、分類法、REST API 端點
    register_post_type('book', [...]);
    register_taxonomy('genre', 'book', [...]);
});

// 3. 前端資源佇列:wp_enqueue_scripts(僅前端)
add_action('wp_enqueue_scripts', function() {
    wp_enqueue_style('my-plugin', plugin_dir_url(__FILE__) . 'assets/style.css');
    wp_enqueue_script('my-plugin', plugin_dir_url(__FILE__) . 'assets/app.js', ['jquery'], null, true);
    wp_localize_script('my-plugin', 'MyPluginAjax', [
        'ajaxurl' => admin_url('admin-ajax.php'),
        'nonce'   => wp_create_nonce('my_plugin_nonce'),
    ]);
});

// 4. 後台選單:admin_menu
add_action('admin_menu', function() {
    add_options_page('My Plugin', 'My Plugin', 'manage_options', 'my-plugin', 'my_plugin_settings_page');
});

// 5. AJAX 處理:wp_ajax_{action} / wp_ajax_nopriv_{action}
add_action('wp_ajax_my_action', 'my_ajax_handler');
add_action('wp_ajax_nopriv_my_action', 'my_ajax_handler'); // 未登入用戶
function my_ajax_handler() {
    check_ajax_referer('my_plugin_nonce', 'nonce');
    wp_send_json_success(['message' => 'OK']);
}

// 6. 內容修改:the_content filter
add_filter('the_content', function($content) {
    if (is_singular('book')) {
        $content .= '';
    }
    return $content; // 必須回傳
});

// 7. 輸出頁腳:wp_footer action
add_action('wp_footer', function() {
    echo '';
});

5. 關鍵 Hook 執行順序(精簡版)

  1. muplugins_loaded
  2. plugins_loaded ← 插件主檔案多在此掛載早期邏輯
  3. load_textdomain
  4. auth_cookie_valid / set_current_user
  5. init ← 註冊 CPT、Taxonomy、Rewrite Rules、REST Endpoints
  6. wp_loaded ← 處理 POST/Redirect、表單提交
  7. parse_request / wp / template_redirect
  8. get_header → wp_head
  9. loop_start → the_post → the_content (Filter)
  10. get_footer → wp_footer (Action)
  11. shutdown

6. 除錯技巧

  • Query Monitor 外掛:查看 Hook 執行順序、耗時、SQL、HTTP 請求。
  • add_action('all', function($hook) { error_log($hook); }); 記錄所有觸發的 Hook(慎用,極其噪雜)。
  • wp cli hook list 列出所有 Hook 及掛載的回調。

7. 現代開發建議

  • 使用 Composer 管理依賴,wpackagist-plugin/... 或私有倉庫。
  • 採用 PSR-4 自動載入,主檔案只 require vendor/autoload.php 並啟動 Service Provider。
  • 利用 WP CLI 測試:wp plugin activate my-plugin、wp eval 'var_dump(apply_filters("the_content", "test"));'。
  • 單元測試:wp scaffold plugin-tests + phpunit,搭配 WordPress/WordPress-Coding-Standards。

原文《淺析Wordpress的插件執行流程》重構,補充完整 Hook 生命週期、現代開發工具鏈、除錯技巧與最佳實踐。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved