Software Engineering in WordPress, PHP, and Backend Development

Category: Articles (Page 2 of 255)

Personal opinions and how-to’s that I’ve written both here and as contributions to other blogs.

Working in Software Is Better Than Hardware (Bugs Are Part of the Job)

The dictionary defines archenemy as “the chief enemy” where enemy is defined as:


  1. a person who feels hatred for, fosters harmful designs against, or engages in antagonistic activities against another; an adversary or opponent.
  2. an armed foe; an opposing military force:
    The army attacked the enemy at dawn.

And I mention this because the original states that “bugs will be your arch-enemy for life.

The arch-enemy of many a software developer.

Obviously, this is hyperbole but if your primary job as a programmer is to ship functioning code and bugs prevent said code from working or it results the program yielding unexpected behaviors then, yes, you will forever be fighting them.

Bugs Are Part of the Job

Before writing this article, I thought about the various different projects I’ve worked on during my career and how bugs have affected each of them (including ones I’ve introduced).

  • Some of these projects include enterprise grade web applications with various data center used throughout the United States.
  • Others are small utilities that have maybe a dozen users.
  • And then there’s a variety of everything in between.

There’s no succinct way to talk about how bugs are introduced, grow, change, are squashed, and are reintroduced into a software system.

Just another day in the life. Write code and deal with bugs.

The original article has a pretty good statement:

So the truth is you should assume that everything has bugs. That’s why experienced devs never trust their code if it runs successfully on the first try. Even if the QA engineer reports a bug, assume that the bug ticket has a “bug” and check for everything.

And I really like the idea that “you should assume that everything has bugs.” That’s the bottom line, full stop.

I Choose Software Over Hardware Any Day

Software is a broad term to encompass all types of products we use:

  • iOS apps
  • Android Apps
  • TV apps (regardless of the vendor)
  • Web apps
  • Extensions
  • Plugins
  • Utilities
  • Operating systems
  • Components
  • And on and on it goes.

It’s amazing human beings can collaborate to produce such things (regardless of the environment) and that these things continue to work despite the high potential and likelihood for error that exists.

He’s astounded as much as I am that any of this works.

Sure, we can put in place all types of automated testing around the code, we can hire QA engineers to test all sorts of edge cases, and we can have entire support departments dedicated to handling user feedback, requests, bug reports, and so on.

And still they persist.

Rather see them as an enemy that has to be defeated, overcome, or reduced into nothing as if there are two sides two a war, I prefer to see them as just as part of the job.

Yes, they are frustrated, yes fixing one can lead to another, and yes sometimes an improper merge can end up bringing a previously squashed bug back into the codebase.

But it happens.

For what it’s worth, one of the things that I’ve told myself over the years is that I’d much rather be working on software rather than hardware because the former affords us, among many other things, the ability to ship fixes, patches, and updates in a far easier manner than a physical product.

Software Developers and Technical Articles in the Era of AI

Site analytics are funny things regardless of how you use them (that is, through marketing, engagement, content, and so on). I say this because analytics give us information about:

  • how long people are reading our content (per article, even),
  • how many people are reading what we write,
  • how much people are reading what we write,
  • how often people are returning to read what we write,

And all of this coalesces into informing the things about which we write and how we write about it. At least, this is my experience.

The day to day experience of understanding analytics through the use of two mice.

Despite having all of this analytical information available, AI is changing the type of content we publish.

For technical writers specifically, this should give us pause on if there’s not a slightly wider range of related topics about which we can write that continue to contribute to the field in which we work.

Technical Articles in the Era of AI

As far as analytics, SEO, AI, and all of the other related technologies to blogging are concerned, I still hold to the mantra I’ve had for over a decade:

Write what you want on a given topic and don’t over think it.

This has proven the most useful and has transcended whatever changes have happened within the industry.

I primarily write because I enjoy the process, but it’s afforded opportunities that wouldn’t otherwise be available (the least of which isn’t developing solid friendships with people I’ve met in conferences or online).

Even still, I – like anyone else who’s maintained a site for a reasonable amount of time – still pay attention to some level of information analytics provide.

On Analytics

I rarely do a legitimate deep dive on the analytics of my site. Generally, I like to see:

  • the number of visitors over time,
  • how much time they are spending on the site or on each article,
  • and the bounce rate.

I’ve developed this habit in part because I’ve been writing technical content for so long it’s of some interest to see if people are [still] paying attention to it. But, as the advent of AI (see this post) has hit the mainstream of this industry, there’s been a change in how we all look up technical content.

And where analytics may have been useful for a very long time, there’s now another dimension to the field.


Given blogs and technical articles have helped train the LLMs we’ve so quickly adopted, it raises questions.

Is it useful to continue writing technical articles?

  • If the content we wrote helped train the LLMs then are new articles also continue to add to the data set the LLMs are using?
  • If more and more developers – myself included – are going to an LLM to help solve problems first (versus a search engine), how much less valuable are other sites and blogs becoming?

I still think there is value in treating a blog like a public notebook of sorts even if it’s just for personal reasons.

If not, then what else is there for technical writers to publish?

  • I don’t think there’s any shortage of content engineers have to write because so much of our job is more than just development, architecture, and so on.
  • The amount of things tangentially related or even adjacent to our work provide plenty of content that’s useful for other people to read (take articles like this and or this, for example).
  • As the technical aspect of our jobs may be enhanced – or substitute whatever word you’d like – by AI, there is still a human factor.

Clearly stated: As long as a human experience exists as something unique, it has potential to be an article that cannot be wholly generated through the statistical probability of words assembled through generative AI. (Though I’d be foolish to say that it can be a challenge to discern the difference between what a person has written and what has been generated.)

Writing technical articles does not have to be published into the void.

Though it may be easier to refer to ChatGPT for a technical question rather than a blog, that doesn’t mean a developer has nothing about which to write in relation to the field. For example, just as I could write about my day-to-day in working from home as a father of three an trying to maintain a schedule for reading, writing, exercising, music, work, and continued growth in what I do for a living, so can any one else. (Or so should everyone else?)

Software Developers Should Expand Topics

Ultimately, the way our work is altered through the advent of AI is undeniable. And though it may mean there are some changes in how we get our work done, it also informs how we can continue to contribute content related to what we do in our day-to-day. (This is something I used to do way back when, too.)

In other words, looking up how to properly sanitize data before it enters a database is going to be something the current – and the next – generation will ask an LLM. But looking up how to be productive as a remote engineer living in rural Georgia in a family of five, three of which are kids, is something AI cannot answer.

And perhaps that’s an area in which we could easily – and should – expand our content

How To Identify Anonymous Functions in WordPress

Heads Up! Originally, I wanted to include both how to identify anonymous functions in WordPress and how to unhook them; however, the more I began writing about the topic, the longer the article became.

So I’ve split the content into two articles: This one outlines how to identify anonymous functions registered with hooks. A future article will detail how to de-register said functions.

Previously, I explain how to identify and register anonymous functions in WordPress. As I wrote in the introduction:

As I started writing, it became obvious it’s helpful to understand what PHP does behind-the-scenes when anonymous functions are registered.

So during the first article, I spend time explaining both how anonymous functions are registered – which is clear enough – and how anonymous functions are managed internally by PHP.

If you haven’t read the article, I urge you to do so. But if you’re opting out, the short of it is this:

  1. You register an anonymous function with an associated WordPress hook,
  2. PHP generates an ID via hashing for the anonymous function so that it can be managed internally.

It sound easy enough, but problems arise if you want to programmatically identify those anonymous functions. PHP keeps track of them and the functions fire as they are intended but what happens if you, as a developer, want to access those functions to deregister them?

Identify Anonymous Functions

Before looking how, or if, it’s even possible to deregister anonymous functions, it’s important to know how to identify anonymous functions programmatically. That is, if we know we’re working in an environment where anonymous functions have been registered, how do we actually find them?

This programmer is completely at a loss for where to find an anonymous function.

Again, since these functions are registered with WordPress hooks and since these functions have an ID internally generated by PHP, there’s code we can write to help us understand where these functions are registered.

In the following bit, I’ll show exactly how to do this. This won’t necessarily explain what the code is going nor will it explain who registered the code, but it’ll give us some insight as to what anonymous functions are registered with which hooks.

And that’s a good starting place.

Finding Anonymous Functions

Before using any other specific tools, I’m going to use the following:

It’s not pretty, this isn’t the usual set of tools with which I’d recommend using, but it’s a starting point that’s going to demonstrate the point. In other words, this is a quick and dirty approach to get started.

Further, we’ll be writing anonymous functions in the theme’s functions.php to make it easier to have parity with the content of the article.

With all of that in place, I’ll open functions.php and then add the following code:

add_action('wp_head', 'listRegisteredFunctions', PHP_INT_MAX);
 * Lists all the registered functions.
 * @return void
function listRegisteredFunctions() {
     global $wp_filter;

     echo <<<HTML
     <div style="background:white; font-size:14px;">
    echo <<<HTML

This uses the global $wp_filter object which holds information on all of the referenced actions and filters with WordPress. Note also that I’m setting this up to fire in the wp_head hook and that I’m using PHP_INT_MAX to make sure it has the highest priority (so it fires as late as possible).

Note: I do not recommend nor even suggest using PHP_INT_MAX in a production environment because it makes it incredibly difficult to add anything after that registered hook. This is just for demonstration purposes.

If you run this and then refresh the homepage of your installation, you’re going to see a lot of information. Some of it will make sense, some of it may not. Regardless, it’s going to be a lot of data. And as interesting as it is, there’s not much we can do with it.

If there’s not much to do about it, might as well laugh about it.

To help simplify what it renders, let’s look at something that’s registered with just one of the hooks. Specifically, let’s look and see what’s registered with the wp_enqueue_scripts hook. This hook is one that most anyone who has worked with theme or plugin development has used and something that’s going to have a number of associated callbacks within the context of a theme.

Note, I’m going to use a similar function as used above. I will, however, be changing the actual code in the function. Additionally, note that I have some guard clauses defined for early return so that if nothing is registered with the hook or if there are no callbacks, the function won’t run.

The code looks like this:

add_action('wp_head', 'listRegisteredFunctions', PHP_INT_MAX);
 * Lists all the registered functions.
 * @return void
function listRegisteredFunctions() {
     global $wp_filter;

    if (!isset($wp_filter['wp_enqueue_scripts'])) {

    // Get all functions/callbacks hooked to wp_enqueue_scripts
    $callbacks = $wp_filter['wp_enqueue_scripts']->callbacks;
    if (empty($callbacks)) {

    // ...

It’s not going to render anything yet, though, because I don’t have the code for actually rendering the callbacks and functions associated with the hook. To do that, we can iterate through the callbacks and get each function and its associated priority.

To render that, we need to add:

echo '<pre>';
foreach ($callbacks as $priority => $functions) {
    foreach ($functions as $function) {
        print_r([$function, $function['function']]);
        echo '<br />';
echo '</pre>';

The two important things to take away from the above code are:

  1. I’m adding the function and the $function['function'] to an array that’s dumped by print_r.
  2. $function['function'] contains a reference to the callback function.

In the outer foreach loop, note that $functions is the associative array representing the callbacks hooked to the wp_enqueue_scripts. In the inner loop, $function has information about the callback and $function['function'] is the actual callback itself.

In the environment I’m using to test this code, I’m running the twentytwenty theme and I’ve added the above code to functions.php. If you’re following along with the same – even if it’s a different theme – you’ll likely see something like this written out to the screen:

    [0] => Array
            [function] => twentytwenty_register_scripts
            [accepted_args] => 1

    [1] => twentytwenty_register_scripts

I’ve opted to use this as an example because it’s prefixed with twentytwenty_ meaning it’s likely going to be found within the theme. And when I search for this function in the theme within my IDE, I found the following:

 * Register and Enqueue Scripts.
 * @since Twenty Twenty 1.0
function twentytwenty_register_scripts() {
    // Code remove to keep the code succinct.

add_action( 'wp_enqueue_scripts', 'twentytwenty_register_scripts' );

The important thing to note here is that we see the function twentytwenty_register_scripts is, in fact, registered with the wp_enqueue_scripts hook.

The purpose of looking at this is to see that we’re successfully able to find code that’s registered with our hook of choice. The next challenge, though, is finding anonymous functions that are registered with the same hook.

Sometimes, printing out the code and searching for anonymous functions helps. Supposedly.

You can argue that it’d be more helpful to go ahead and find all anonymous functions registered with this hook but let’s first create out own so we can get an idea as to how this looks.

When doing this, you’ll see how complex, though not impossible, managing anonymous functions can be.

Creating Our Own Anonymous Function

First, comment out the code that’s listing all of the functions registered with the wp_enqueue_scripts hook.

This dude thought registering a function with a hook literally meant he needed a hook.

Next, let’s add our own anonymous functions to functions.php. This will render a message at the top of the page and it will allow us to use previously written code to track track this anonymous function.

add_action('wp_enqueue_scripts', function () {
    echo <<<HTML
        <div style="border:1px outset gray; padding: 1em;background:#ccc;position:fixed;top:0;left:0;z-index:99; width: 100%;">
            This is a a sample anonymous function.
}, 0, 10);

When you refresh the page you’re on, you should see something like this:

The next step will be to run the previously written code and attempt to locate this function.

Now let’s reintroduce the code responsible for printing all of the functions registered with the hook. Assuming you’ve done everything correct, you’ll notice a new piece of data rendered on the page.

Specifically, it’ll read like this:

    [0] => Array
            [function] => Closure Object

            [accepted_args] => 10

    [1] => Closure Object


Assuming there are no other anonymous functions in your code, then this is the function we just wrote and the one we’re looking to manage.

When dressed like this in a place like that, you’re ready to manage all of the code.

So this raises the following two questions:

  1. How can we relate an anonymous function to a specific hook?
  2. How can we de-register this function?

Since we know that PHP generates an internal ID for closures and since we have an anonymous function currently hooked to the wp_enqueue_scripts hook, let’s see what we can do.

Relating Anonymous Functions to Specific Hooks

First, let’s update the code in functions.php so that it dumps all of the information for the closure. I’ll show the code first then explain what it’s doing:

add_action('wp_enqueue_scripts', function () {
    $backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
    echo '<pre>';
    echo '</pre>';
    // The original code is here...

Note this part is going to require a bit of functionality offered by PHP. Some of you who have worked with PHP for years may be familiar with this; some of you may not. And if not, that’s okay! I’ll explain it then share a bit more about it.

In the function, I’m grabbing information from one of the built-in PHP functions called debug_backtrace and then I’m using the DEBUG_BACKTRACE_PROVIDE_OBJECT constant to help.

This is a breakdown of each argument and the function to which they are passed:

  • debug_backtrace() is a function in PHP that returns a backtrace, which is an array of associative arrays containing function call information. It provides a snapshot of the call stack at the point where it is called, showing the hierarchy of function calls leading up to that point.
  • DEBUG_BACKTRACE_PROVIDE_OBJECT is a constant flag that can be used as an option when calling debug_backtrace(). When this flag is set, each frame in the backtrace will contain an entry named ‘object’ representing the current object instance.
  • The 2 is an optional parameter specifying the number of stack frames to return in the backtrace. In this case, it limits the backtrace to two frames.
  • And, for what it’s worth, a “frame” refers to a specific level or entry in the call stack (which is, essentially, the order in which functions are called).

This is what a call to this function actually does:

  • The first frame is the frame where debug_backtrace() is called (that is, the anonymous function itself).
  • The second frame is the frame where the function that called debug_backtrace() resides.
  • By limiting the frames to two, you get information about the current function (anonymous function in this case) and its caller.

As I mentioned at the start of this section, using functionality like this is something that comes with having worked with PHP for several years. I don’t remember exactly when I learned it myself. Regardless, that’s an advantage of articles like this, I guess (read: I hope) – it exposes you to new things of which you may not have otherwise been aware.

And yes, de-registering hooks in WordPress is challenging but it’s through these type of facilities that we should be able to do so. When you view this code in your browser, you should see something like the following located in the data you’ve printed to your browser:

array(2) {
  object(Closure)#741 (0) {

Recall from the previous article that PHP does two things when registering callbacks:

  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.

And since this is an anonymous function, the ID we see in the print out above is the ID PHP generated when registering the function.

Before We Deregister The Function…

As I stated throughout this article: I wanted to include all of the information in the previous article and this article to explain exactly what PHP is doing, how to locate registered closures, and how to deregister them, but the amount of time it takes to explain how to do all of the above takes longer than I anticipated.

It took so long for this guy to explain the concepts, his audience fell asleep. Maybe his handwriting should be better.

As such, I’m going to pause here. There’s plenty of material to review in terms of the PHP internals as well as work that can be done to inspect your own anonymous functions.

In the next article, I’ll walk through a process – regardless of how manual it is – for how to deregister the functions.

Until then, incorporate some of the code here and also see what other anonymous functions have been registered throughout your codebase.

It’s Hard to Estimate Writing Code (And Always Will Be)

There’s an old – relatively speaking of course – quote that says:

There are only two hard things in Computer Science: cache invalidation and naming things.

Phil Karlton

Though I think coming up with estimates for completing a task may be a close third (or at least somewhere pretty high on the list).

A computer programmer, stressed, as she tries to come up with a clever name for a variable.

Having worked as a contractor, in an agency, and in product work, I can say though there may be small variations on how estimates are handled, the basics are the same such that it goes something like this:

  • A task is a unit of work to be completed as part of a larger project,
  • Each task has a start date,
  • Developers are asked to estimate how long it will take to complete said task.

Here’s the thing: There’s usually an ideal goal in mind for when the task should be a completed. If it can be completed in the ideal range, great; if not, then it has to be scoped so that it fits within a reasonable range. Any work left over moves into another phase of work.

So from the outset of the task, we’re expected to estimate how long it will take to complete the the work even though it’s the period in which we know the least amount the problem domain.

This is why estimates are hard.

There are a few caveats to this that I’ll get to in just a moment, but I want to point out that this is simply part of the software development process. I’d say that it’s almost law at this point (but there are plenty of shops and developers that always surprise us, so I perhaps it’s just an unwritten rule that can be broken).

Suffice it to say, estimating tasks is an inevitable part of the job of a developer. As such, it helps to know what it actually entails and it helps to have some suggestions on how accurately estimate a task.

How to Estimate Writing Code

Yet another programmer staring at a kanban boarding trying to figure out if the next task can fit in the sprint.

Depending on which type of software development lifecycle you and/or your team use, the way tasks are estimated may be different but they are different nonetheless.

  • The Waterfall Method usually has phases each with its own plan that cascade down into the next phase.
  • An Agile Method will use something like sprints that then will use some type of measurement (perhaps story points or days or hours) to estimate how long a task will take and then a sprint will only consist of a set number of story points. If a task exceeds that maximum amount of points, it’s either re-scoped or moved to the next sprint.
  • The Iterative Model works something like creating an MVP and then slowly working to improve upon the base (though how long each team wants to spend on working up from the MVP varies).
  • And so on.

There are many models that exist within software development but the one thing they all have in common is this:

  • Everything that needs to be built can be reduced to a task and a task can be measured in a unit relative to the project.
  • Whoever your stakeholders may be have an ideal number for the units they think are reasonable and they will often vary from what you, as a developer, think is reasonable.

This is where I whole-heartedly agree with the original article. It states:

Business revolves around numbers. Every project has its cost, and to calculate the cost, management needs to estimate how long it will take to build a certain feature

Your boss counting his money from all of the time spent by properly estimating taxes.

So, as far as this article is concerned, this leaves two questions:

  1. What are the caveats mentioned earlier in the article?
  2. How do we accurately determine estimates?


Whenever I think of someone responsible for building software, I think of people who are working with a consistent set of tools and a tech stack with which they know well.

For some, this may be the Microsoft stack of SQL Server, .NET, and whatever frontend tooling they are using (perhaps its a native GUI or a webpage). For others, this may be MySQL, PHP, and something to render user interface components within a browser.

And even each of those have their own subset of technologies they use. My point, though, is that developers usually have a set of technologies they use to build the solutions for which they are tasked. These technologies are used day-to-day in their job and are primarily how they build their solutions. (This is why we hear if someone is a “Microsoft shop” or a “Laravel shop” or whatever term you want to use.)

This is a software development shop that looks exactly like where we all work, right?

The point of discussing estimates is not to get bogged down into what’s used to build the solution at hand; instead, it’s something more along the lines of “given the tools we typically use, how long will it take to build this solution.”

So the primary caveat is that I’m assuming you consistently work with the same technology stack. This matters because the longer you work with it, the easier certain problems can be solved.

But if it was consistently consist, we wouldn’t be discussing estimates, would we?

Determining Estimates

As I mentioned earlier, we know the least about the problem space from the outset of the project. Yet this is when we’re tasked with estimating how long it’s going to take to complete a task.

Since we don’t know what we don’t know when we don’t know, we absolutely have to be generous when estimating our tasks.

Later, when you start to work on that feature, you encounter many problems that you weren’t aware of when you gave time estimates. Then you need to compensate for the wasted and hope not to break the deadline.

Three scenarios can play out from this. In no particular order:

  1. You may not finish the task within the allotted time.
  2. You finish the task exactly with what time was estimated.
  3. You finish ahead of schedule.

In each of these cases, there’s always more than can be done. But a good rule of them, as written in the linked article:

If I need to deliver some feature, and I think it will take 2 days, I add roughly 40% more time to it, just to be safe. So, in this case, the estimate will be 3 days. Later, if I am done in 2 days, I can just deliver it earlier.

In other words, don’t over estimate yourself and even when you fill confident, estimate more than you think you will need. This will help build out confidence both for you, your team (as well as your project manager, if you have one), and the business.

Your manager terrified of the estimates you’ve given.

If you don’t estimate properly every now and then, that’s okay; but always err on the side of liberal estimates. You absolutely need to account for the things for which you aren’t even aware yet.


I’d be remiss if I didn’t clarify what happens in the three points above for how three scenarios of estimation play out so I’ll do that here (and recap them, too).

  1. If you don’t finish the task in the allotted time, it may be punted to the next unit of work, you may have the ability to ship part of the work while creating a new task in the next phase of work.
  2. If you finish the task exactly with what time was estimated then you’ve estimated well (was it a fluke?) and the feature can ship when expected.
  3. You finish ahead of schedule then you’re getting good at estimating (assuming it wasn’t also a fluke :) and you’ll be able to pick up another task to work on even if it can’t ship in this phase of work.

Ultimately, the longer I’ve been in the industry and using generally the same tech stack, the more I continue believe in the idea of overestimating my tasks. This allows for exploration of the problem domain and the ability to develop a full, working solution within the phase. In other words, if I was to give my past self advice, this is what I would’ve liked to have had on hand.

It’s helpful to remember Parkinson’s Law:

Parkinson’s law is the observation that the duration of public administration, bureaucracy and officialdom expands to fill its allotted time span, regardless of the amount of work to be done.

This is something you may occasionally hear in software development circles. And though it didn’t originally apply to it, it sometimes happens that way. Thus, part of our job is to make sure that we don’t fall to trap to this and that we properly estimate writing code and stick to it.

This part is oftentimes more of an aspect of self discipline than anything else.

If you’re a veteran – regardless of what technologies you use – you probably already have a strategy in place to help with estimates.

But if not or if you’re new to the field, perhaps this will help.

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 '<style>
            body {
                background-color: #f3f3f3;

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 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 '<style>
            body {
                background-color: #f3f3f3;

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 '<style>
            body {
                background-color: #f3f3f3;

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.

« Older posts Newer posts »

© 2024 Tom McFarlin

Theme by Anders NorenUp ↑