WordPress Best Practices: Global functions vs. classes

A couple of months ago I started a thread on the wp-hackers mailing list. I wanted to know whether the WP’s core team intended to use PHP classes or sets of global functions with global variables going forward. I prize consistency above all else in my coding and wanted to follow their lead. Here’s what I posted:

It seems there’s two competing views on whether a set of functions or a class should be used in core. For example, the relatively recent transients API is a set of functions, but could have just as easily been a class. Is there some reasoning behind the decision to use a set of functions instead of a class? Or is it coders choice?

To be clear, I’m not for or against using a set of functions instead of a class. And the transients API is great the way it is. If there’s no difference in performance, I personally don’t care either way. However, I am for consistency and don’t see a reason why we should use both techniques.

And what about static class variables rather than global variables? WP stopped supporting PHP4 last year, so is there any reason not to use static class variables for new development?

The discussion that ensued was excellent. For me, the crux of the conversation was delivered by @nacin, with a detailed post about the core team’s work with classes and globals. I recommend reading the whole post, but here are few gems:

Don’t be surprised if WP_Post happens in 3.5 or 3.6.

Someone mentioned PHP 5.3 namespaces, and that makes me laugh. In two years, PHP 5.3 adoption (in terms of WordPress sites) has gone from 4% to 10%. Not holding my breath.

Rewriting code for the sake of rewriting code is not a good use of our time.

That also does not mean we’re going to use classes everywhere. There are plenty of situations where procedural code is going to be better.

I am at the point where I will fight hard to prevent any more globals be added to core; we’ve been rather good about this for at least a year now.

That said, static class variables (as suggested) aren’t exactly any better. They’re not.

Global state (a global variable, a static method, a static property, what have you) is not testable.

The last point about global state not being testable really hit home for me. I read through all of the referenced articles and it really opened my eyes to how code needs to be structured to be testable. I’ve been aiming to get into test-driven development and this was a big step in that direction.

Also, it’s clear to me now that I should avoid using the global state and look at implementing a class before a set of global functions, but not be afraid to use global functions if they work better for the situation.