Identifying and Registering Anonymous Functions in WordPress

Identifying and Registering Anonymous Functions in WordPress

Originally, this article started as an explanation for how to remove anonymous functions registered with WordPress. As I started writing, it became obvious it’s helpful to understand what PHP does behind-the-scenes when anonymous functions are registered.

This dude clearly doesn’t understand anonymous functions. The eyes give it away.

Furthermore, this helps give a deeper understanding as to why registered anonymous functions can be problematic and how we can deal with them on a technical level.

Finally, it’s worth noting that I don’t take a hard stance on if anonymous functions should never be used or not. There’s a time and a place where it makes sense, and there’s a time and a place where it doesn’t need to be done. That’s a topic to cover in the future, though.


I’ve mentioned this before, but I’m not in the business of sharing the author of any given tweet [anymore] for the sake of how X/Twitter mobs can behave. Besides, it’s the content of the tweet that warrants a discussion, not the person who said it.

Some time ago, I saw this come across my feed:

I do wish developers would stop using WordPress hooks with (what I think are called) anonymous functions […].

They are very hard if not impossible to unhook.

As mentioned, the how to deregister anonymous functions and the “whether or not this is a good idea” are topics for another post. For now, I want to share what happens whenever an anonymous function is registered with a hook in WordPress.

Named Functions in WordPress and PHP

Brainstorming names for named functions. Naming things is hard.

First, an example:

add_action('admin_init', 'tmAddBackgroundColor'); function tmAddBackgroundColor() {     echo ''; }

In the code above, we’re using a named function – as opposed to an anonymous function – to do the following:

  • add_action('admin_init', 'tmAddBackgroundColor') hooks the tmAddBackgroundColor function to the admin_init action. It tells WordPress to execute the specified function when the admin area is initialized.
  • The actual function adds a custom CSS style to the admin area.

If I was a third-party developer who wanted to remove this functionality, then I’d locate the function and invoke the following call somewhere in my code:

remove_action('admin_init', 'tmAddBackgroundColor');

This is an obvious benefit to named functions. Even if the function is located in a different namespace, it’s possible to remove the action by prefixing the function name with the name of the namespace.

What happens with anonymous functions, though?

Anonymous Functions in WordPress and PHP

You don’t have to a name an anonymous function. You might as well just stare at a wall.

If you’re familiar with anonymous functions, then the following code should be clear. If not, though, take a look and I’ll explain what’s happening after the block:

add_action('admin_init', function () {     echo ''; }); 

Anonymous functions are generally useful when you have a small, one-time callback that doesn’t need to be referenced elsewhere in your code.

Obviously, the functionality is the same, but it raises the question: How do we call remove_action on this function? That’s something we’re working towards, but first, here’s what happens in PHP whenever you’re working with anonymous functions.

PHP Closures, Closure IDs, and Registration in WordPress

An ID registered for a conference.

Before reading any further, note that a closure in PHP is a way to create an anonymous function.

Just like what’s demonstrated above, it allows us to write a piece of code that can be registered with a hook or, more generally, passed around as a variable. The latter part of this will make sense after we look at what PHP does when an anonymous function is created.

PHP does two things after you register an anonymous function with a WordPress hook:

  1. Generates an ID for the closure. To generate a unique identifier for this closure, WordPress uses the spl_object_hash() function.
  2. Associates the ID with the callback. The generated closure ID is then associated with the callback function, allowing WordPress to track and manage callbacks even when they are anonymous functions.

Given this, another way to write and associate an anonymous function with WordPress would be like this:

$adminInitCallback = function () {     echo ''; };  add_action('admin_init', $adminInitCallback);

And we can get the ID of the closure as generated by PHP by passing the variable to the spl_object_hash function. For example:

$closureId = spl_object_hash($adminInitCallback);

And that will return the ID that’s generated by PHP and associated with the specific hook in WordPress.

But Still, Deregistering Anonymous Functions?

Though this doesn’t help explain how to deregister anonymous functions, it does help explain how things work within PHP.

This will make it easier to explain ideas around anonymous functions ands hooks in a future post.

Advertisement

About The Author

Tom

Archives