函数文档

add_action()

💡 云策文档标注

概述

add_action() 是 WordPress 中用于向动作钩子添加回调函数的核心函数,属于 Action API 的一部分。它允许插件或主题在特定执行点或事件发生时运行自定义 PHP 函数。

关键要点

  • 函数签名:add_action( $hook_name, $callback, $priority = 10, $accepted_args = 1 ),其中 $hook_name 和 $callback 为必填参数,$priority 和 $accepted_args 为可选参数。
  • $priority 参数控制回调函数的执行顺序,数值越小优先级越高,默认值为 10。
  • $accepted_args 参数指定回调函数接受的参数数量,默认值为 1,需与 do_action() 调用传递的参数匹配。
  • 函数始终返回 true,内部实现基于 add_filter()。
  • 在类中使用时,需通过数组语法传递回调,如 array( $this, 'method_name' ) 或静态方法 array( get_called_class(), 'method_name' )。
  • 可通过闭包传递变量,但需注意在可分发主题或插件中避免使用匿名闭包,以支持 remove_action() 操作。

代码示例

// 基本用法
add_action( 'save_post', 'wpdocs_my_save_post', 10, 3 );

function wpdocs_my_save_post( $post_ID, $post, $update ) {
    // 处理保存逻辑
}

// 在类中使用
class WP_Docs_Class {
    public function __construct() {
        add_action( 'save_post', array( $this, 'wpdocs_save_posts' ) );
    }

    public function wpdocs_save_posts() {
        // 处理保存逻辑
    }
}

// 使用闭包传递变量
$myvar = 'Hello World';
$action_wp_footer = function($arguments) use ($myvar) {
    echo $myvar;
};
add_action('wp_footer', $action_wp_footer, 100, 1);

注意事项

  • 在可分发主题或插件中,避免在类构造函数中直接添加钩子,推荐使用单独的 hooks() 方法以提高可重用性和避免重复添加。
  • 使用闭包时,应将其赋值给变量以便后续通过 remove_action() 移除,避免使用匿名闭包导致无法移除。
  • 确保 $accepted_args 参数与 do_action() 调用传递的参数数量一致,可通过搜索代码库查找匹配的 do_action() 调用来确定。
  • 相关函数包括 do_action() 和 remove_action(),用于触发和移除动作钩子。

📄 原文内容

Adds a callback function to an action hook.

Description

Actions are the hooks that the WordPress core launches at specific points during execution, or when specific events occur. Plugins can specify that one or more of its PHP functions are executed at these points, using the Action API.

Parameters

$hook_namestringrequired
The name of the action to add the callback to.
$callbackcallablerequired
The callback to be run when the action is called.
$priorityintoptional
Used to specify the order in which the functions associated with a particular action are executed.
Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action.

Default:10

$accepted_argsintoptional
The number of arguments the function accepts.

Default:1

Return

true Always returns true.

More Information

Usage

add_action( $hook, $function_to_add, $priority, $accepted_args );

To find out the number and name of arguments for an action, simply search the code base for the matching do_action() call. For example, if you are hooking into ‘save_post’, you would find it in post.php:

do_action( 'save_post', $post_ID, $post, $update );

Your add_action call would look like:

add_action( 'save_post', 'wpdocs_my_save_post', 10, 3 );

And your function would be:

function wpdocs_my_save_post( $post_ID, $post, $update ) {
// do stuff here
}

Source

function add_action( $hook_name, $callback, $priority = 10, $accepted_args = 1 ) {
	return add_filter( $hook_name, $callback, $priority, $accepted_args );
}

Changelog

Version Description
1.2.0 Introduced.

User Contributed Notes

  1. Skip to note 11 content

    Using with a Class
    To use add_action() when your plugin or theme is built using classes, you need to use the array callable syntax. You would pass the function to add_action() as an array, with $this as the first element, then the name of the class method, like so:

    /**
     * Class WP_Docs_Class.
     */
    class WP_Docs_Class {
    
    	/**
    	 * Constructor
    	 */
    	public function __construct() {
    		add_action( 'save_post', array( $this, 'wpdocs_save_posts' ) );
    	}
    
    	/**
    	 * Handle saving post data.
    	 */
    	public function wpdocs_save_posts() {
    		// do stuff here...
    	}
    }
    
    $wpdocsclass = new WP_Docs_Class();

  2. Skip to note 12 content

    Using with static functions in a class
    If the class is called staticly the approach has to be like below as $this is not available. This also works if class is extended. Use the following:

    /**
     * Class WP_Docs_Static_Class.
     */
    class WP_Docs_Static_Class {
    
    	/**
    	 * Initializer for setting up action handler
    	 */
    	public static function init() {
    		add_action( 'save_post', array( get_called_class(), 'wpdocs_save_posts' ) );
    	}
    
    	/**
    	 * Handler for saving post data.
    	 */
    	public static function wpdocs_save_posts() {
    		// do stuff here...
    	}
    }
    
    WP_Docs_Static_Class::init();

  3. Skip to note 13 content

    To pass a variable to the called function of the action, you can use closures (since PHP 5.3+) when the argument is not available in the original coded do_action. For example:

    add_action('wp_footer', function($arguments) use ($myvar) { 
        echo $myvar;
    }, $priority_integer, $accepted_arguments_integer);

  4. Skip to note 14 content

    Simple Hook
    To email some friends whenever an entry is posted on your blog:

    /**
     * Send email to my friends.
     *
     * @param int $post_id Post ID.
     * @return int Post ID.
     */
    function wpdocs_email_friends( $post_id ) {
    	$friends = 'bob@example.org, <a href="mailto:susie@example.org">susie@example.org</a>';
    	wp_mail( $friends, "sally's blog updated", 'I just put something on my blog: <a href="http://blog.example.com" rel="nofollow ugc">http://blog.example.com</a>' );
    
    	return $post_id;
    }
    add_action( 'publish_post', 'wpdocs_email_friends' );

  5. Skip to note 16 content

    I urge you, don’t attach your hook callbacks inside class’ constructor.

    Instead of implementing official example most upvoted in this thread, opt for decoupled solution. You have one more line of code to write, but objects become more reusable and less error-prone (consider, what would happen if you call new WP_Docs_Class() twice in your code, following Codex example).

    /**
     * Class WP_Docs_Class.
     */
    class WP_Docs_Class {
    	
    	/**
    	 * Initiate all hooks' callbacks in a separate method.
    	 */
    	public function hooks() {
    		add_action( 'save_post', array( $this, 'wpdocs_save_posts' ) );
    	}
    
    	/**
    	 * Handle saving post data.
    	 */
    	public function wpdocs_save_posts() {
    		// do stuff here...
    	}
    }
    
    $wpdocsclass = new WP_Docs_Class();
    $wpdocsclass->hooks();

  6. Skip to note 17 content

    Passing parameters while using in a Class
    To pass parameters to your method in a Class while calling it with add_action, you can do as following:

    public function __construct() {
        // Actions
        add_action('init', array($this, 'call_somefunction'));
    }
    
    /**
     *    Intermediate function to call add_action with parameters
     */
    public function call_somefunction() {
        $this->somefunction('Hello World');
    }
    
    /**
     *    Actual function that does something
     */
    public function somefunction($text) {
        echo $text;
    }

  7. Skip to note 18 content

    How to add an action that calls a function (with parameters) from an instantiated class:

    $admin_menu_hider = new AdminMenuHider( UserManagement::get_internal_users() );
    			add_action(
    				'wp_before_admin_bar_render',
    				function () use ( $admin_menu_hider ) {
    					$admin_menu_hider->change_greeting_message( 'Hello' );
    				}
    			);

  8. Skip to note 19 content

    Accepted Arguments
    A hooked function can optionally accept arguments from the action call, if any are set to be passed. In this simplistic example, the echo_comment_id function takes the $comment_id argument, which is automatically passed to when the do_action() call using the comment_id_not_found filter hook is run.

    /**
     * Warn about comment not found
     *
     * @param int $comment_id Comment ID.
     */
    function echo_comment_id( $comment_id ) {
    	printf( 'Comment ID %s could not be found', esc_html( $comment_id ) );
    }
    add_action( 'comment_id_not_found', 'echo_comment_id', 10, 1 );

  9. Skip to note 20 content

    To prevent runtime errors due to easy typo errors (defensive programming) and prevent pollution of the global namespace use closures instead of function names. The sample code adjusted:

    /**
     * add a save post hook
     */
    add_action( 'save_post', function( $post_ID, $post, $update ) {
       // do stuff here
    }, 10, 3 );