TL;DR: As much as I like using object-oriented programming for writing code, it’s not the only way to write code. The same goes for WordPress-centric code, too. When writing solutions for WordPress, don’t set out to write everything in an object-oriented way. Don’t forget procedural programming in WordPress.


For the last few months, I’ve been writing a handful of small utility plugins (for lack of a better word) for WordPress. These are things that are designed to do at least one of the following:

  • add a feature that I wish exists but doesn’t,
  • improve functionality of the administration area to make achieving a given task easier,
  • introduce functionality that’s easier for a sites that have a large database of users,
  • and more.

As someone who’s historically been one to go on and on about why we should be using object-oriented programming, I’ve not been doing much of that in these plugins.

Instead, I’ve been using some features of PHP, like namespaces and autoloading, to keep the code running in its own area to prevent potential conflicts with other plugins. I’ve also been using PSR12 with procedural programming.

For as much as I’ve written about object-oriented programming, I don’t think I’ve written enough (and I certainly won’t do so in a single post 🙂) about procedural programming.

But that doesn’t mean now isn’t as good as time as any.

Procedural Programming in WordPress

When I wrote the first draft of this post, it was much longer – it felt excessive. Especially when the ultimate point I want to make is this:

Just because there are programming paradigms that seek to make code more testable, maintainable, and model real world entities does not mean it’s the ultimate goal of how to write code.

If a plugin uses at least one action or filter, then it’s possible to set it up this way:

  • a bootstrap to start the plugin,
  • a subscriber to listen for a given hook,
  • an object to instantiate whenever the hook fires

This is, more or less, the recipe for setting up object-oriented code in WordPress.

But that doesn’t mean the alternative isn’t something that’s viable or that’s just as robust.

A Practical Case in Point

Assume, for a moment, you want to do some minor processing on the content before it’s rendered in the browser. Maybe you’re looking for a substring, maybe you want to prepend content, or maybe you want to inject a piece of markup into the middle of the content.

You can still take the approach that’s above:

  • set up the bootstrap to instantiate a registry for the plugin,
  • create a subscriber to listen for the_content filter,
  • invoke a ContentProcessor or something similar whenever the filter fires.

But if the plugin is doing one thing and it’s something that can happen just before the content is sent from WordPress to the browser, perhaps the above approach is overkill?

What if, instead of that, the plugin was set up to:

  • register an anonymous function with the_content
  • process the code within the anonymous function

The code is still easy to read, it’s easy to maintain, and it does one thing without overcomplicating the job it’s meant to do. Further, you can still use your preferred coding standard and docblocks without sacrifice.

Further, if you’re using PSR12, it would look something like this:

add_filter(
    'the_content',
    /**
     * Removes any shortcodes from within the content.
     *
     * @param string $content The unprocessed content.
     *
     * @return string $content The processed content.
     */
    function (string $content) {
        if (!is_singular() || !in_the_loop() || !is_main_query()) {
            return $content;
        }

        // Manipulate the content and prepare to return it.
        return $content;
    }
);

Obviously, the second to last line is where the core logic for the plugin would come into play, but the gist of the case I’m making is still evident.

And that is:

When you’re working on something that can be achieved with as little code and as clear code as possible, aim to use that when possible.

This Isn’t a Rule

I don’t like making hard and fast rules so this is merely a suggestion. And the more code you write and the more work you do in this space, the more experience you’ll get that will help you intuitively know when a certain architecture will be best suited to the solution at hand.

Perhaps I’m writing this for myself, though. For as much as I appreciate and lean towards object-oriented programming, I’ve been doing less of it lately simply because I’ve not had a need for it when something else arguably simpler will suffice.