WordPress and the Curious Case of PHP Namespaces

For part two of my series on Rethinking PHP Development in WordPress, I wanted to write about three significant elements of object oriented programming: classes, interfaces, and namespaces. A big reason I wanted to write about them together is because I think they’re so integral to understanding the way PHP developers who cut their teeth on WordPress learn their craft. However, I felt that might get a bit verbose and keep me from hitting that “Publish” button, so I wanted to focus on just one segment of that topic today: namespaces.

What is a namespace?

Before we can talk about namespaces, let’s focus on a second on symbols. In computer programming, a symbol is simply something that has a human-readable form. A function is a symbol. Class names are symbols. So are variables. We use symbols in programming because they help us understand what we’re trying to make our programs do.

We have control over what we name our symbols, the same way that our parents named us, and we name our own pets, children, and computer hardware (you’ve named your computer, right?).

In real-life, symbols can be complicated. Have you ever worked somewhere that had more than one Chris, Travis, Sam, or (C/K)arl (I do!). We differentiate between first names by passing down our family names, but sometimes, that’s not even enough. In the U.S., we have Social Security Numbers so we can differentiate – on paper, at least – between the thousands of John Smiths and Jane Jacksons in our country.

Last names and identifying numbers are a type of namespace. Basically, a namespace is a way to ensure that something that must be unique in your system is, in fact, unique.

In PHP, we have to ensure that all of our symbols are unique in order to prevent fatal errors. And, in the WordPress community, at least, we’ve established a couple of different ways of attempting to achieve that goal.

Function prefixes

Everyone who has written WordPress code for any length of time has been told time and time again to “prefix their functions.” What does that mean? Well, let’s say I had a function that registered a product post type:

<?php
function register_post_type() {
    register_post_type( 'product', array( /* My options... */ ) );
}
add_action( 'init', 'register_post_type' );

If you’ve been writing PHP code in WordPress for any length of time, hopefully the problem is evident to you right away, because in this particular example, I’m declaring a function name that is named the exact same as the WordPress core function I’m calling within it. This is called a naming collision, and it PHP, it will generate a fatal error, which causes your code not to complete execution.

They way we’ve gotten around this for years in the WordPress ecosystem is two-fold. First, we prefix our function calls to reduce the chance that someone else (usually another plugin) has declared a function with the same name as us. And second, we wrap that function declaration in some code that checks whether that function has already been declared. Here’s another example:

<?php
if ( ! function_exists( 'jmw_register_post_type' ) {
    function jmw_register_post_type() {
        register_post_type( 'product', array( /* My options... */ ) );
    }
    add_action( 'init', 'jmw_register_post_type' );
}

The function_exists method in PHP allows us to check whether someone else has created a function with the same name before we make a declaration for our own. The jmw prefix in this example attempts to further minimize the chance that someone has created another function with the same name.

This approach is perfectly suitable, and has worked reasonably well for many developers over the history of the WordPress project. If you examine the code from the WordPress plugin repository, chances are high that you’ll see this pattern a lot.

Classes as a namespace

Over time, developers began separating their code a bit more, grouping like-functions into separate files, and exploring the use of a class-based system for further namespacing. I think this happened for at least two reasons:

  1. Classes can have the same names as functions, but you can store a lot more information in a class, which means you can make big collections of functions.
  2. WordPress developers, after writing functional code for years, were eager to try their hand at object-oriented programming.

Re-hashing the example from the previous section, we might have something like this:

<?php
class JMW_Custom_Post_Types {
    public static function register_product() {
        register_post_type( 'product', array( /* My options... */ ) );
    }
}
add_action( 'init', array( 'JMW_Custom_Post_Types', 'register_product' );

As with the ! function_exists check in the previous example, we might also wrap the class declaration in a ! class_exists check here, too, just to make sure that our JMW_ prefix is sufficient.

I want to reiterate here: this is fine. The thing about computer programming, particularly in PHP, is that there are a lot of ways to do things, and whatever gets your code shipped and out to the world is more important than which particular approaches you used.

That said, I want to tell you about a third approach, because there is currently not a single* example of it in all of WordPress core.

The namespace keyword

The namespace keyword has been a part of PHP since version 5.3. It avoids the prefixing and class-based approaches ot avoiding symbol collisions in the language. Here’s another example of the function-based approach from earlier, but using the keyword instead:

<?php
namespace JMW;

function register_post_type() {
    \register_post_type( 'product', array( /* My options... */ ) );
}
add_action( 'init', 'JMW\register_post_type' );

Notice anything weird? Well, in this example, I’m prefixing the call to WordPress’s register_post_type function with a backward slash. That’s because I need to tell PHP that I want to use a method from the global namespace, which is to say: I want to use the register_post_type method that didn’t declare a namespace, because WordPress does not currently have any namespace conventions in core.

That said, the code in the above example won’t fail because PHP allows us to have two functions with the same name, so long as we identify distinct namespaces for each of them, just like how two people named Travis can work at the same company (sometimes, you might just give them nicknames, even if they have different last names. Nicknames are another form of namespacing.)!

How is this better?

It may not be evident at first why this makes a difference. Adding a namespace to the top of your file might be more work, but what it really does is frees you up from the way things have always been done. If, for example, you’re a plugin developer and you really like using short, concise function names, you can use them without fear of symbol collision from WordPress core or other plugins. Heck, you can use them without fear of symbol collision from your own code!

Let me demonstrate what I mean with a few more examples:

<?php
namespace JMW\Product_Post_Type;

function register() {
        register_post_type( 'product', array( /* My options... */ ) );
}
add_action( 'init', 'JMW\Product_Post_Type\register' );
<?php
namespace JMW\Faculty_Post_Type;

function register() {
    register_post_type( 'faculty', array( /* My options... * ) );
}
add_action( 'init', 'JMW\Faculty_Post_Type\register' );

The above examples might be two separate functions files name product-post-type.php and faculty-post-type.php, respectively. Although they both contain a register method, you could include them both in your functions.php file without worrying about a symbol collision, because they’re each namespaced differently. This gives developers a lot of flexibility to use short function names without worry that there will be a symbol collision, even within their own codebase.

Summary

These examples only really scratch the surface. In the broader PHP ecosystem, namespaces are frequently used not just to prevent symbol collision, but also to dictate class file organization, such as in the PSR-4 standard recommended by the PHP Framework Interoperability Group. In their configuration, every package (e.g., a WordPress plugin) has both a vendor and a package namespace at the top-level:

<?php
namespace JMichaelWard\MyGreatPlugin;

In PSR-4, the above example would be considered the root namespace, which means any files with that namespace could be located in the root of a directory indicated by the developer. Namespaces with extra levels would map to a sub-directory. Example:

<?php
namespace JMichaelWard\MyGreatPlugin\PostType;

The PostType sub-namespace would suggest that I have a directory named PostType where all of my classes are kept. This approach helps simply class autoloading, which is perhaps another post altogether.

Needless to say, namespacing your function and class files in WordPress, even if core isn’t yet doing it, can provide some great benefits. It allows you to confidently use shorter method names (particularly when paired with the <vendor>/<packagename> approach I just described). It allows you to group code into directories when paired with class autoloading. And, least importantly, but important nonetheless: it allows you to use a language feature that has been available in PHP for nearly 12 years.

I hope this post inspires you to experiment with PHP namespacing, and sets you on your journey for further exploration of the server-side language of WordPress.

Footnotes

* WordPress core contains the PHPMailer library, which in fact, uses the native PHP namespace keyword.