admin管理员组

文章数量:1277281

The goal of this question is:

  • to be able to interpret WP docs better
  • to understand what's exactly happening in this scenario
  • to verify what I'm thinking is correct

I came across this code.

    function register() {
        ...
        add_filter( "plugin_action_links_$this->plugin", array( $this, 'settings_link' ) );
    }

    public function settings_link($links) {
        $settings_link = '<a href="admin.php?page=alecaddd_plugin">Settings</a>';
        array_push( $links, $settings_link );
        return $links;
    }

When I debug settings_link($links), I see $links is an array with a 'deactivate' key and value.

Looking at wp dev docs, it seems $links relates to the $actions parameter.
apply_filters( "plugin_action_links_{$plugin_file}", string[] $actions, string $plugin_file, array $plugin_data, string $context )

I noticed though, that the other parameters, $plugin_file, $plugin_data, $context, were not available in the debugger.

I then changed the code as follows.

        function register() {
            ...
            add_filter( "plugin_action_links_$this->plugin", array( $this, 'settings_link' ), 10, 4 ); );  // change 1
        }

        public function settings_link($links, $plugin_file, $plugin_data, $context ) {  // change 2
        $settings_link = '<a href="admin.php?page=alecaddd_plugin">Settings</a>';
            array_push( $links, $settings_link );
            return $links;
        }

Low and behold, now the other parameters $plugin_file, $plugin_data, $context are now available in my function.

I suspect calling add_filter while only passing a callback, is some form of workflow to make things faster & easier.

Can somebody clarify further, or just confirming, what's exactly happening here?
Is this behavior documented somewhere in the official docs?

The goal of this question is:

  • to be able to interpret WP docs better
  • to understand what's exactly happening in this scenario
  • to verify what I'm thinking is correct

I came across this code.

    function register() {
        ...
        add_filter( "plugin_action_links_$this->plugin", array( $this, 'settings_link' ) );
    }

    public function settings_link($links) {
        $settings_link = '<a href="admin.php?page=alecaddd_plugin">Settings</a>';
        array_push( $links, $settings_link );
        return $links;
    }

When I debug settings_link($links), I see $links is an array with a 'deactivate' key and value.

Looking at wp dev docs, it seems $links relates to the $actions parameter.
apply_filters( "plugin_action_links_{$plugin_file}", string[] $actions, string $plugin_file, array $plugin_data, string $context )

I noticed though, that the other parameters, $plugin_file, $plugin_data, $context, were not available in the debugger.

I then changed the code as follows.

        function register() {
            ...
            add_filter( "plugin_action_links_$this->plugin", array( $this, 'settings_link' ), 10, 4 ); );  // change 1
        }

        public function settings_link($links, $plugin_file, $plugin_data, $context ) {  // change 2
        $settings_link = '<a href="admin.php?page=alecaddd_plugin">Settings</a>';
            array_push( $links, $settings_link );
            return $links;
        }

Low and behold, now the other parameters $plugin_file, $plugin_data, $context are now available in my function.

I suspect calling add_filter while only passing a callback, is some form of workflow to make things faster & easier.

Can somebody clarify further, or just confirming, what's exactly happening here?
Is this behavior documented somewhere in the official docs?

Share Improve this question edited Oct 1, 2021 at 11:18 Jacob Peattie 44.1k10 gold badges50 silver badges64 bronze badges asked Oct 1, 2021 at 11:11 progonkpaprogonkpa 1033 bronze badges 2
  • 1 I'm not sure I fully understand. Before you had add_filter('..', [..], 10, 1) (because 10 and 1 are the defaults), now you have add_filter('..', [..], 10, 4). With the 4 you instruct WP to pass 4 arguments to this method. And yes, add_filter and add_action basically allow you to change somebody else's behaviour. Otherwise you'd have to override their code, which would get undone by an update. – kero Commented Oct 1, 2021 at 11:42
  • 1 @kero that's the missing piece of information I needed. I didn't know the default value for the number of arguments was 1. That explains everything. I could have known from the add_filter docs.. anyway, thank you. – progonkpa Commented Oct 1, 2021 at 11:48
Add a comment  | 

1 Answer 1

Reset to default 2

The important thing to note is that action and filter hooks are mostly just standard PHP callback behaviour.

The second argument passed to add_filter() should be a PHP Callable. When the filter is applied with apply_filters(), that callback is just run through the core PHP function call_user_func_array(). Any additional arguments to apply_filters() are then passed as $args to your callback.

The WordPress specific behaviour is around defining the number of arguments your callback accepts. When you add a filter with add_filter(), the 4th argument defines the number of arguments that the callback accepts. WordPress then only passes that number of arguments when it calls call_user_func_array().

Normally passing more arguments than a callback accepts is perfectly fine. The exception is built-in PHP functions, which will throw an error. For example, this will throw an error:

call_user_func_array( 'addslashes', array( 'argument one', 'argument two' ) );

To prevent this WordPress makes you declare how many arguments your callback accepts, and trims the number passed to call_user_func_array() accordingly.

There is an old ticket about deprecating this behaviour here, and you can follow the discussion to see why that never happened. The short version is performance and backwards compatibility.

本文标签: pluginsWhat exactly happens to function argument availability when using a filter