My Namespace Vision

Painting expressing young woman with universe sprouting from her handWordPress does not make use of namespaces at all. Plugin and Theme developers can, but WordPress core does not. They have this weird notion that they need to keep compatibility with PHP 5.2.4 even though it was released in August, 2007 – over a decade ago. The latest in the 5.2.x branch is 5.2.17 which was released end of 2011, over six years ago. The latest in 5.3.x branch is 5.3.29, released in August 2014. The latest in 5.4.x branch is 5.4.45, released in September 2015. The latest in 5.5.x branch is 5.5.38, released in July 2016.

All of those have something in common. They no longer even receive security patches from the upstream PHP developers, and they all have known security vulnerabilities. It is not safe to use them. It is not safe to use them. It is not safe to use them. It is not safe to use them.

But WordPress insists they be supported. No one should be using any version of PHP older than from the 5.6.x branch (which only receives security fixes) and really people should be using PHP 7.1 or 7.2. Pay a coder to fix your web apps if they break in PHP 7.

Anyway, because they insist on supporting very old versions of PHP, what I see as the right way to leverage namespaces is not possible with WordPress because they insist on supporting a decade old long deprecated version of PHP that simply does not have namespace support. In the 5.2.x series, everything ran in what we now call the root namespace.

The Root Namespace

This should only be classes and functions that are part of PHP itself, including binary extensions loaded when the server starts (usually PECL modules).

Any other classes loaded by the web application should be in a namespace.

Web Application Namespace

The web application should have a namespace used for classes specific to the web application. With WordPress, that namespace would probably be called \WordPress and it would be one level below the root namespace. Only classes provided by the project for the project should be in that namespace. Within that namespace, additional namespaces could exist, e.g. \WordPress\Admin or \WordPress\Network or \WordPress\Upgrade or whatever is needed to categorize the classes logically so it is easy for a code hacker (the good kind) to find what they are looking for if they do not know where it is.

Functions can be namespaced too although honestly it is probably better to put them as static methods in a namespaced class.

Web Application Vendor Third Party Namespace

Web applications often uses classes written by other people.

When these classes are not namespaced, they should be ported to a namespace within the Web Application Namespace. When they already are namespaced, that namespacing should be used.

Plugin / Theme Namespace

Plugin and Theme developers who create classes should use their chosen vendor name as the first level namespace and if the class is part of a collection of related classes, a product namespace.

The class files themselves however should be a different root than the Web Application and Web Application Vendor Third Party classes.

The Autoloader

The autoload script when it needs to load a class from the Web Application namespace should only look in the directory that has the classes that came with the web application. For all other classes, it should first look in the directory that has the classes that came with the web application, and then look in the directory for the Plugin / Theme namespace.

What this does, it prevents plugin and theme developers from using the web application vendor namespace and it also prevents a web application or theme developer from having a different version of a third party class load. This provides stability to the core product, it will always have the version of the classes it expects.

I suppose a third party developer could explicitly load a file containing a class that breaks the rules, but it will not happen by accident.

Class Maps

A lot of people like class maps. What they are is a text file with key => value pairs where the key is the fully qualified name of the class and the value is the filesystem location of the class.

They are only really needed when you do not follow PSR-2 convention of every class in its own file with a filename that matches the class name. I would rather not have them. But what you can do to boost performance is use APCu caching to cache the location on the filesystem when you do find the class to load, so that you essentially have an in-memory class map. That’s what I do for one of my secret projects and it works very well. However my suspicion is that it only possibly makes a real world difference when your server uses platter drives. For server grade SSDs that quality hosts use, I doubt it makes a lick of difference.

Plugins and Extensions

Plugins and extensions to a web application should have two kinds of pseudo-classes: pseudo-private and pseudo-public.

A pseudo-private class is a class that is only intended to be used by the plugin or extension it was written for. It would be bundled with the plugin or extension and would use the namespace of the vendor, but it would not be loaded with the autoloader, it would not need to be. The location of the file containing it would be known and relative to the scripts that need it.

A pseudo-public class is a class that is intended to provide a stable set of methods any plugin or class could use. These are what would be loaded by the autoloader, and all pseudo-public classes by a vendor should be packaged together in a single distribution though vendor/package would be okay for vendors that literally have hundreds of classes. Since classes are not loaded unless they are needed, there is no harm in simply having every class by a vendor installed.

So for example if the extension DooHicky wanted to use a class in the vendor namespace \JoeCoolCoding\XMLStuff then the installer for DooHicky would ask the installer for all classes in the \JoeCoolCoding\XMLStuff namespace, which would either result in the install of that specific namespace if JoeCoolCoding split them up, or simply all classes in the \JoeCoolCoding namespace if they were not split up, which is what I would recommend as the norm.

The installation of DooHicky would not need to result in the installation of any plugins or extension by JoeCoolCoding, just the installation of the pseudo-public classes.

In Conclusion

Namespaces are very useful in organizing classes and make it very clear to the error logs what package the class is part of, and they also help avoid collisions because you do not need the silly if (! class_exists('foo')) {} or if (! function_exists('bar')) {} calls that currently exist all through WordPress code including core plugins.

The autoloader takes care of loading the class, and when you want a specific version of a class, you can stick it in your own namespace and always get it even if others have different versions loaded.

Leave a Reply

Your email address will not be published. Required fields are marked *

Anonymity protected with AWM Pluggable Unplugged