Class Autoloader

Autoloading Class Files

Rubix Cube with WordPress LogoAutoloaders have been a part of PHP for a very long time. Namespaces have been a part of PHP almost as long.

WordPress does not make use of either, which is really unfortunate.

With autoloaders, you do not need to worry about things like the phpinclude path being correct or even requiring the file in your project, just use it as if it is already loaded and if it is not already loaded, the autoloader will look for it and load it.

With namespaces, you do not have to worry about class name collisions. It is still possible, but as long as two vendors aren’t using the same namespace, their classes simply will not have collisions.

Now obviously for the autoloader to find a load the class your application wants to use, the autoloader has to know where to find it.

There were several defacto standards, but the first widely adopted standard was PSR-0. It has since been deprecated and replaced with PSR-4.

With a PSR-4 autoloader, each class to be autoloaded MUST be in a namespace at least one level below the root namespace, and the first level namespace below the root namespace SHOULD correspond with the creator of the class, usually referred to as the Vendor. When multiple classes are tied together as part of a Product, usually those classes are in a \Vendor\Product namespace.

For example, if WordPress ported their project to use a PSR-4 autoloader, they would likely use the \WordPress namespace for all classes that are part of WP Core, and likely have some lower level namespace, e.g. \WordPress\Network for network related classes and \WordPress\Admin for admin related classes.

Third parties writing plugins and themes would use a different namespace. JetPack for example would likely have its classes in something similar to the \Automattic\JetPack nameapace.

Another property of classes that conform to the PSR-4 standard, each class must be in its own file that has the same filename as the class name but with a .php extension added.

For example, the existing WordPress class WP_Http_Curl (currently in a file named class-wp-http-curl.php) would have the filename WP_Http_Curl.php.

With namespaces though, they might just call the class Curl and put it in the \WordPress\Http namespace, in which case the filename would be Curl.php.

With a PSR-4 autoloader, the namespaces are a clue to help the autoloader find where the file that contains the class it needs to load is located. Take a class with the fully qualified namespace of \WordPress\Http\Curl for example.

A PSR-4 autloloader would look for that class to be located in a directory called {BaseDir}/WordPress/Http/Curl.php where {BaseDir} is a directory you have instructed the autoloader to look in for namespaces classes.

Even though WordPress does not have a PSR-4 style autoloader, the PSR-4 standard makes autoloaders easy to write, so I wrote one so that we all can benefit from this tremendous advancement in Web Application design that WordPress is slow to embrace.

Installation

To install the autoloader, place the following single-file plugin into your WordPress “Must Use” plugin directory: https://gist.github.com/AliceWonderMiscreations/4ba7209256f0e2b38d59a8787d164f63

The “Must Use” plugin directory is usually located at wp-content/mu-plugins but it does not exist by default, so you may have to create it. The reason for placing the plugin file in that directory is because it will always be loaded and always loaded before anything in wp-content/plugins or wp-content/themes is loaded. This is important, so the autoloader can already be registered with PHP when normal plugins and themes are loaded.

Once the plugin is installed, you can start adding PSR-4 compliant classes.

By default, the autoloader in that plugin will use wp-content/wp-psr4 as the base directory, but you can configure the base directory to be elsewhere just be defining the WP_PSR4 constant in your wp-config.php file. For example:

define('WP_PSR4', '/usr/local/share/wp-psr4');

That method is useful when you have more than one WordPress install on your server, they can share a common directory for PSR-4 compliant namespaced classes.

Whether you decide to use the default location or define your own base directory for the classes, you will have to manually create the base directory where the collection of classes are to reside.

Class Collections

One of the major advantages of autoloading classes is that the classes are only loaded when they are actually needed, and do not need to be part of an activated plugin to be available.

Some of my classes, such as my webfont class, are not associated with any of my plugins, they exist solely to provide a needed API or plugin and theme developers. Some of my classes were written to be used by my plugins but still provide a useful API that others may want to use without requiring my plugins to be installed or activated.

For this reason, I choose to simply just bundle of my classes intended for WordPress as one collection of classes. What other developers will choose to do is up to them.

You can download a zip archive of all my classes here: AWonderPHP-1526395797.zip

Alternatively, you can get my classes from github: https://github.com/AliceWonderMiscreations/AWonderPHP

After cloning that repo, in the top level directory run the command

php createZipArchive.php

That will create the zip archive for you.

Either way, unpack the zip archive in the directory you created for PSR-4 classes and they will now be available for use.

Updates

At present, updating the classes has to be done manually. Created an automated installer and updater is on my todo list, it will happen.

PEAR Autoload

The PEAR autoload has not yet been tested but should would.

PEAR predates autoloaders and namespaces, so it emulates namespaces in the class names by using an underscore between the intended namespaces.

The WordPressAutoload class will load PEAR classes. The class uses the constant WP_PEAR_PATH to define the directory where PEAR modules are installed. If that constant is not defined in your wp-config.php file, the autoloader will look for PEAR in some common places and define it if it finds it.

The WP_PEAR_PATH constant is actually only used as a fall-back. Traditionally, the PEAR directory is defined in the PHP include path. My autoloader respects that, and will look within the PHP include path first, only looking in the defined WP_PEAR_PATH if it does not find it within the PHP include path.

ClassMap

At this time, I have no intention of supporting loading classes with a ClassMap. Such a function may be useful to plugin and theme developers who have many classes specific to the theme or plugin but are not always needed, so I may change my mind about that in the future.

What a ClassMap does for those who do not know, it is a simple key => value array where the key is the fully qualified name of the class and the value is the path to the class to be loaded.

They are useful if the class does not use a namespace, if the name of the class does not match the filename, if there is more than one class in the file, and when the classes are not installed where the autoloader can automatically detect them. That last case is where it could be of benefit to plugin and theme developers. I would still recommend they follow conventions of using a namespace, once class per file, filename matching the class name. Those conventions are good to follow whether or not an autoloader is being used.

Leave a Reply

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

Anonymity protected with AWM Pluggable Unplugged