函数文档

add_filter()

💡 云策文档标注

概述

add_filter() 是 WordPress 核心函数,用于将回调函数绑定到过滤器钩子,允许插件或主题在运行时修改数据。它通过指定优先级和接受参数数量来控制回调的执行顺序和参数传递。

关键要点

  • add_filter() 用于向过滤器钩子添加回调函数,以修改 apply_filters() 传递的值。
  • 参数包括 $hook_name(钩子名称)、$callback(回调函数)、$priority(优先级,默认10)和 $accepted_args(接受参数数量,默认1)。
  • 回调函数可以接受从0到 apply_filters() 传递参数总数的任意数量参数,但 $accepted_args 必须与实际接受参数数匹配。
  • 函数始终返回 true,不验证回调函数有效性,需开发者自行确保。
  • 支持多种回调类型:普通函数、类静态方法、实例方法、匿名函数。
  • 过滤器回调只能修改第一个参数($value),其他参数仅提供上下文,不可更改。

代码示例

// 基本用法:修改示例值
function example_callback( $example ) {
    // 修改 $example
    return $example;
}
add_filter( 'example_filter', 'example_callback' );

// 指定优先级和接受参数数
add_filter( 'hook', 'example_callback', 10, 2 );

// 使用类方法作为回调
add_filter( 'media_upload_newtab', array( 'My_Class', 'media_upload_callback' ) ); // 静态方法
add_filter( 'media_upload_newtab', array( $this, 'media_upload_callback' ) ); // 实例方法

// 使用匿名函数
add_filter( 'the_title', function( $title ) { return '<strong>' . $title . '</strong>'; } );

注意事项

  • add_filter() 不检查回调函数是否存在,若钩子触发时回调未定义,将导致警告错误。
  • 在回调函数中输出内容(如 echo)可能导致输出位置不可预测,因为返回值被用于其他地方。
  • 在 WordPress 启动前添加过滤器时,可手动操作 $wp_filter 全局数组,但移除过滤器需使用 remove_all_filters()。
  • 确保 $accepted_args 与回调函数实际参数数一致,否则可能丢失参数。

📄 原文内容

Adds a callback function to a filter hook.

Description

WordPress offers filter hooks to allow plugins to modify various types of internal data at runtime.

A plugin can modify data by binding a callback to a filter hook. When the filter is later applied, each bound callback is run in order of priority, and given the opportunity to modify a value by returning a new value.

The following example shows how a callback function is bound to a filter hook.

Note that $example is passed to the callback, (maybe) modified, then returned:

function example_callback( $example ) {
    // Maybe modify $example in some way.
    return $example;
}
add_filter( 'example_filter', 'example_callback' );

Bound callbacks can accept from none to the total number of arguments passed as parameters in the corresponding apply_filters() call.

In other words, if an apply_filters() call passes four total arguments, callbacks bound to it can accept none (the same as 1) of the arguments or up to four. The important part is that the $accepted_args value must reflect the number of arguments the bound callback actually opted to accept. If no arguments were accepted by the callback that is considered to be the same as accepting 1 argument. For example:

// Filter call.
$value = apply_filters( 'hook', $value, $arg2, $arg3 );

// Accepting zero/one arguments.
function example_callback() {
    ...
    return 'some value';
}
add_filter( 'hook', 'example_callback' ); // Where $priority is default 10, $accepted_args is default 1.

// Accepting two arguments (three possible).
function example_callback( $value, $arg2 ) {
    ...
    return $maybe_modified_value;
}
add_filter( 'hook', 'example_callback', 10, 2 ); // Where $priority is 10, $accepted_args is 2.

_Note:_ The function will return true whether or not the callback is valid.
It is up to you to take care. This is done for optimization purposes, so everything is as quick as possible.

Parameters

$hook_namestringrequired
The name of the filter to add the callback to.
$callbackcallablerequired
The callback to be run when the filter is applied.
$priorityintoptional
Used to specify the order in which the functions associated with a particular filter 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 filter.

Default:10

$accepted_argsintoptional
The number of arguments the function accepts.

Default:1

Return

true Always returns true.

More Information

  • Hooked functions can take extra arguments that are set when the matching do_action() or apply_filters() call is run. For example, the comment_id_not_found action will pass the comment ID to each callback.
  • Although you can pass the number of $accepted_args, you can only manipulate the $value. The other arguments are only to provide context, and their values cannot be changed by the filter function.
  • You can also pass a class method as a callback.
Static class method:
add_filter( 'media_upload_newtab', array( 'My_Class', 'media_upload_callback' ) );
Instance method:
add_filter( 'media_upload_newtab', array( $this, 'media_upload_callback' ) );
  • You can also pass an an anonymous function as a callback. For example:
add_filter( 'the_title', function( $title ) { return '<strong>' . $title . '</strong>'; } );

Source

function add_filter( $hook_name, $callback, $priority = 10, $accepted_args = 1 ) {
	global $wp_filter;

	if ( ! isset( $wp_filter[ $hook_name ] ) ) {
		$wp_filter[ $hook_name ] = new WP_Hook();
	}

	$wp_filter[ $hook_name ]->add_filter( $hook_name, $callback, $priority, $accepted_args );

	return true;
}

Changelog

Version Description
0.71 Introduced.

User Contributed Notes

  1. Skip to note 9 content

    Example: Let’s add extra sections to TwentySeventeen Front page.
    By default, TwentySeventeen theme has 4 sections for the front page. This example will make them 6

    add_filter( 'twentyseventeen_front_page_sections', 'prefix_custom_front_page_sections' );
    	
    function prefix_custom_front_page_sections( $num_sections )
    {
    		return 6;
    }

  2. Skip to note 10 content

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

    add_filter('wp_footer', function($arguments) use ($myvar) { 
        return $myvar;
    }, $priority_integer, $accepted_arguments_integer);

  3. Skip to note 11 content

    Example: Let display custom length of post excerpt.

    if( ! function_exists( 'prefix_custom_excerpt_length' ) )
    {
    	function prefix_custom_excerpt_length( $length )
    	{
    		return 40;
    	}
    }
    add_filter( 'excerpt_length', 'prefix_custom_excerpt_length', 999 );

    By default, WordPress display 57 character. you can set custom length using above code. this time except length will be 40. it is a nice and easiest use of add_filter.

  4. Skip to note 12 content

    Example: If you want to inject a CLASS/ID CSS in content. Let’s add extra CLASS/ID to post content.

    //Add Class/ID to Post Content
    add_filter('the_content', 'xai_my_class');
    function xai_my_class($content)
    {
        //Replace the instance with the Class/ID markup.
        $string = '<ul'; //your tag
        $replace = '<ul class="detail-list"'; //add your class/id and tag
        $content = str_replace( $string, $replace, $content );
        return $content;
    }

  5. Skip to note 13 content

    In the special case you have to add a filter before WordPress starts, you can create and pre-populate the global $wp_filter array instead of using the not-yet available add_filter (or add_action) function:

    // Instead of add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ):
    $GLOBALS['wp_filter'][ $tag ][ $priority ][] = array(
      'function'      => $function_to_add,
      'accepted_args' => $accepted_args
    );

    WP_Hook::build_preinitialized_hooks will automatically take care of the rest.
    Though to remove your filter, you can only use the remove_all_filters() function.

  6. Skip to note 14 content

    The Callback $function_to_add need not be defined until the Filter hook fires. This means that:

    1. The add_filter function does not check that $function_to_add exists
    2. The function statement for $function_to_add can be defined after the add_filter statement, even in a conditional (e.g. – if block) where the $function_to_add function does not actually exist until after the add_filter function executes
    3. If the Filter hook never fires, an undefined $function_to_add function will not be reported as an error

    Point 3 needs to be considered during Testing or Quality Control

    An undefined $function_to_add function detected when a Filter hook fires is reported as a Warning error:
    Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'reg_public1' not found or invalid function name in /var/www/example.com/public_html/wp-includes/class-wp-hook.php on line 288

  7. Skip to note 15 content

    If you output something inside the callback, the output location is unpredictable.
    Cause: the returned value is actually used somewhere else (more likely a bit far from where the function would be called). Therefore the output will go where the function was called while the return value is used somewhere else. I’m not sure when you would use this though :).

    add_filter( 'the_content', 'wpdocs_append_to_content', 9 );
    
    function wpdocs_append_to_content( $content ) {
            // output something
            echo 'I Don't Know Where I will end up being printed';
    
    	$additional_content = 'Appended to content';
    	$content = $content . $additional_content;
    
    	return $content;
    }

  8. Skip to note 16 content

    Example
    The filter img_caption_shortcode is applied in media.php using the following call:

    // Allow plugins/themes to override the default caption template.
    $output = apply_filters( 'img_caption_shortcode', '', $attr, $content );
    if ( $output != '' )
    	return $output;

    The target filter function will be called with three arguments:

    ” <= This is normally the value the filter will be modifying
    $attr
    $content

    In order for the filter function to actually receive the full argument list, the call to add_filter() must be modified to specify there are 3 arguments on the parameter list.

    add_filter('img_caption_shortcode', 'my_img_caption_shortcode_filter',10,3);
    
    /**
     * Filter to replace the  shortcode text with HTML5 compliant code
     *
     * @return text HTML content describing embedded figure
     **/
    function my_img_caption_shortcode_filter($val, $attr, $content = null)
    {
    	extract( shortcode_atts( array(
    		'id'	=> '',
    		'align'	=> '',
    		'width'	=> '',
    		'caption' => ''
    	), $attr ) );
    	
    	if ( 1 > (int) $width || empty($caption) )
    		return $val;
    
    	$capid = '';
    	if ( $id ) {
    		$id = esc_attr( $id );
    		$capid = 'id="figcaption_' . $id . '" ';
    		$id = 'id="' . $id . '" aria-labelledby="figcaption_' . $id . '" ';
    	}
    
    	return '<figure ' . $id . 'class="wp-caption ' . esc_attr($align) . '" style="width: '
    	. (10 + (int) $width) . 'px">' . do_shortcode( $content ) . '<figcaption ' . $capid 
    	. 'class="wp-caption-text">' . $caption . '</figcaption></figure>';
    }