The global objects $wp_filter
and $wp_actions
hold details about the hooks that are registered and fire during the WordPress page load process.
If you’ve ever looked at any code that use the two objects, it can be difficult to work out how the objects differ and what data each of the objects hold.
Click here to enroll in our Free WooCommerce Coding Course
In this article we’ll take a look at each object, list the differences between them and look at some code samples that illustrate how they work.
wp_filter
The $wp_filter
object holds details of all of the filters and actions that are registered, here are some brief points describing what it does
- Holds details of all actions and filters
- Holds details of the functions linked to each action filter
Here is a code sample that illustrates what the $wp_filter
object does
//declare a global to get access to the $wp_filter object global $wp_filter; //$wp_filter object contains all the actions and filters that have been added via the add_filter or add_action functions //use the isset function to see if an action or filter has been added //returns false - using var_export here as by default PHP echos nothing for false and 1 for true echo '$wp_filter contains an entry for the "my_filter" tag - ' . var_export(isset($wp_filter['my_filter']),true) .'<br>'; //add a filter and function for the my_filter tag add_filter( 'my_filter', 'hwn_simple_filter_function', 1 ); function hwn_simple_filter_function($value) { return $value; } echo 'Called add_filter( "my_filter", "hwn_simple_filter_function", 1 )' . '<br>'; //returns true now we have added the entry via add_filter echo '$wp_filter contains an entry for the "my_filter" tag - ' . var_export(isset($wp_filter['my_filter']),true) .'<br>'; //write out the data for the add_filter entry in $wp_filter echo '<pre style="background:rgba(0,0,0,.1);">' . var_export($wp_filter['my_filter'], true) . '</pre>';
The output from the code above is shown below
wp_actions
The $wp_actions
object only holds information about actions that have been fired during the page load, here is brief summary about what it does and does not do
- Holds details of actions fired on the current page
- Holds details of the number of times each action has been fired
- Does not hold details of actions that have not been fired via the
do_action
function - Can hold details of actions that have been fired using
do_action
but have not been created usingadd_action
Here’s some code that illustrates how $wp_actions
can be used
//declare a global to get access to the $wp_actions object, we'll declare $wp_filter to compare and contrast global $wp_actions, $wp_filter; //$wp_filter object contains all the actions and filters that have been added via the add_filter or add_action functions //$wp_actions object contains entries for all actions that have been fired with the do_action function //use the isset function to see if an action or filter has been added //returns false echo '$wp_filter contains an entry for the "my_action" tag - ' . var_export(isset($wp_filter['my_action']),true) .'<br>'; //add a filter and function for the my_action tag function hwn_simple_action_function($value) { } add_action( 'my_action', 'hwn_simple_action_function', 1 ); echo 'Called add_action( "my_action", "hwn_simple_action_function", 1 )' . '<br>'; //returns true now we have added the entry via add_action echo '$wp_filter contains an entry for the "my_action" tag - ' . var_export(isset($wp_filter['my_action']),true) .'<br>'; //although an entry has been added to $wp_filter when add_action was called //there is still no entry in $wp_actions as we haven't invoked the action using the do_action function echo '$wp_actions contains an entry for the "my_action" tag - ' . var_export(isset($wp_actions['my_action']),true) .'<br>'; do_action("my_action"); echo 'Called do_action("my_action")' . '<br>'; //now we have invoked the action using the do_action function then an entry is added to the $wp_actions object echo '$wp_actions contains an entry for the "my_action" tag - ' . var_export(isset($wp_actions['my_action']),true) . '<br>'; //note that if we call do_action on an action that we have not created an entry for in the $wp_filter object //via the add_action function then the tag is still added to the $wp_actions object do_action("action_not_yet_created_using_add_action"); echo 'Called do_action("action_not_yet_created_using_add_action")' . '<br>'; echo '$wp_actions contains an entry for the "action_not_yet_created_using_add_action" tag - ' . var_export(isset($wp_actions['action_not_yet_created_using_add_action']),true) ."<br>"; //write out the data for the my_action entry in $wp_actions, will return the number of times the action has been fired echo 'my_action has been fired ' . $wp_actions['my_action'] . ' time(s).<br>'; //the $wp_actions['my_action'] value will increase as do_action is called multiple times do_action("my_action"); echo 'Called do_action("my_action")' . '<br>'; do_action("my_action"); echo 'Called do_action("my_action")' . '<br>'; do_action("my_action"); echo 'Called do_action("my_action")' . '<br>'; echo 'my_action has been fired ' . $wp_actions['my_action'] . ' time(s).<br>'; //the did_action function also returns the number of times an action has been fired echo 'my_action has been fired ' . $wp_actions['my_action'] . ' time(s). The value of did_action("my_action") is - ' . did_action("my_action") . '<br>'; //write out the data for the my_action entry in $wp_filter, works the same as it would for a filter echo '<pre style="background:rgba(0,0,0,.1);">' . var_export($wp_filter['my_action'], true) . '</pre><br>';
Here’s an image of the output of the script above
There are a couple of questions I’ve seen regarding using $wp_filter
and $wp_actions
, I’ll answer those quickly before I wrap up this article
Is it Possible to Only List Actions that have been Registered?
You can get most of the way to doing this by listing the contents of the $wp_actions
object but you have to bear in mind that only actions that have been fired via the do_action
function will be present in the $wp_actions
object.
So listing the contents of the $wp_actions
object list actions that have been fired but will not list actions that have been registered using add_action
but not fired using do_action
.
I would guess that in most cases you’ll be able to get the information you need from $wp_actions
but it’s worth bearing the limitation described above in mind.
Is it Possible to Find Out How Many Times a Filter Has Fired?
As far as I’m aware, there is no way to this.
It’s possible to do this for an action using either $wp_actions['<action name>']
or did_action('<action name>')
but WordPress provides no functionality to count how many times a function has been fired.
I assume this is because you may want to know how many times an action has been fired to prevent functionality running too many times (there’s an excellent Stack Exchange thread about this here) but it’s unlikely that you ‘d need to prevent a filter running a certain number of times.
Is it Possible to tell if a Tag in $wp_filter Relates to an Action or a Filter?
The only way I’m aware that you can do this is to check if the tag is in the $wp_actions
object, if it is then the tag is linked to action.
As mentioned in previous answers, there is a scenario when an action can have been registered with add_action
but not fired using do_action
so it won’t appear in the $wp_actions
object. In this scenario, I don’t think there is any way to distinguish an action set-up in this way from a filter.
Final Thoughts
When I first started looking at the $wp_filter
and $wp_actions
objects I struggled to find certain information, so I hope this article has helped to explain the differences between the two objects and how they work.
If you have any further questions, or can provide better answers than I have to the questions above then please don’t hesitate to let me know in the comments.
This post is part of a series about debugging using the $wp_filter
and $wp_actions
objects, you can find the other posts listed below
Click here for more details about the "Learning WooCommerce Development By Example" book
- WooCommerce: View All The Hooks That Are Fired On A Page
- How To Use The Query Monitor Plug-In To List The Filters/Actions On A Page
Further Reading
Here are the official docs for the functions mentioned in this article
Ian – great article. It’s funny you said you have had a hard time finding info on this subject as I have had a hard time finding info on most subjects. I have a million questions on my quest to find out how WordPress actually works, do you have any suggested websites. Know the code seemed to be a real possibility to then find out she closed the site and moved on was off putting. I find that there are lots of sites and ebooks that teach & re-teach the same 20% whereas your article here actually explains the how not just the what. Thanks.
Hi Terry, thanks for taking the time to leave a comment, I’m really pleased you found the article helpful. In answer to your question about other resources, I haven’t really found anything aside from the Know the Code, which as you say, appears to be no longer updated.
I come from a c# background and my instinct is that it would be odd to find something like this almost completely undocumented in that language. It occurred to me that maybe people were using WordPress at a higher level so there just wasn’t a demand for this sort of thing.