Over the last few articles I’ve been looking at the benefits of using class autoloaders and namespaces in PHP. Despite the clear benefits of using these features, WordPress developers tend to shy away from them. One of the big reasons for this is because of WordPress’ continued support of PHP 5.2, which reached its end of life years ago.
Class autoloaders have been available in various forms since before PHP 5.3. However, the more up-to-date class autoloader — as is generally used in PHP development — require namespaces, a feature added in PHP 5.3.
In this article, I will show you how to create and use your own class autoloader, following established PHP community standards. I will also discuss using the Composer autoloader.
I don’t think that WordPress core should adopt an autoloader at this point. I also don’t think that all of the standards for core development— specifically class naming, and not using an autoloader or namespaces — should extend to plugin or site development.
Using features of PHP that are not backwards compatible with PHP 5.2 is an issue with projects that get released publicly.
In my experience, most users who are affected by this have no idea that they are running such an outdated version. Once confronted with that knowledge, and made aware of the security and performance benefits of upgrading, most users will insist that their hosting provider upgrade their PHP version. That update is usually possible with a few clicks in cPanel.
What is a class autoloader?
A class autoloader is a system for automatically loading uninstantiated classes, including the files that contain them. When following an established system for file naming and a standard autoloader, you can reliably use any class, without manually including the file.
Not having to include the file manually sounds like a small thing but it has a big impact: It makes it easier to create small, more manageable and reusable classes. It also allows you to more easily refactor your classes using an IDE that makes doing so easy, such as phpStorm. In addition, it eliminates one more place for human error.
Choosing a standard
The PHP Framework Interop Group is a group of PHP users with voting representatives from the most major PHP frameworks and content management systems — with the notable exception of WordPress. This group sets the standards for common PHP development practices. They have defined two standards for autoloaders: PSR-0 and its successor, PSR-4.
For the most part, these two standards are very similar, however there are two major differences. First, is that PSR-4 requires the use of namespaces, which I discussed in my last article for Torque. Second, the root directory for a project following the PSR-4 standard does not have to match its root namespace.
For the most part, it is better to follow the PSR-4 standard than the PSR-0 standard it replaced. That is, unless PHP 5.2 backwards compatibility is an issue — in which case the PSR-4 standard can not be used, since it requires namespaces.
Not choosing a standard
You do not have to follow a standard to use class autoloading. Nor does it require the use of a special autoloading class or the use of Composer autoloader. You can make your own.
Following a standard makes it easier to use Composer, and it allows you to share one autoloader for multiple libraries. The latter case is especially useful in full-site development, when you develop multiple plugins, each for a specific function.
The Composer autoloader does not require following the PSR-0 or PSR-4 standard. But following one of those standards does make it much easier to use. If you do not follow one of those standards, you can always use Composer’s classmap to autoload your classes using the Composer autoloader.
Using the Composer Autoloader
One of the easiest ways to utilize a class autoloader is rely on Composer’s autoloader by pushing all of your code into composer libraries. This makes it easier to reuse and share your code. I covered creating Composer libraries in a previous article for Torque.
Using the Composer Autoloader, is as simple as adding to your code:
require_once( 'vendor/autoload.php' );
For full-site development, it may be possible to have one vendor directory for the entire site. For plugin development and other cases you may end up with many vendor directories. That is OK, though it will make deployments a little trickier.
Using a PSR-4 Autoloader
Using a PSR-4 autoloader is very easy, as long as you namespace your classes correctly. Each library has a root directory and namespace. Each class must have the same name as the file and if you are nesting namespaces, then the file directory structure must match the namespace hierarchy.
For example, if your root namespace is “fun” and you have a class called “process” in the “shortcodes” sub-namespace than the following must be true about this class:
- It should be in a file called “process.php”
- It should be in a directory called “shortcodes”
- That directory should be a subdirectory of the main namespace
Here is what that class would look like:
<?php namespace fun\shortcode; class process { }
Of course, for this to work, your library must be registered with the autoloader in use. This can be done in one of two ways. If it is a composer library, then you simply define that in your composer.json file.
"autoload": { "psr-4": {"fun\\": "src/"} }
The above example assumes the library’s root directory is called “src.” It doesn’t have to be, but by convention it should be.
The root level of a Composer library generally contains only a readme, composer file, and two directories (“src” and “test”). The latter will contain the library’s unit tests.
If you need to use your own autoloader, simply copy the example autoloader from the PSR-4 standard. Be sure to prefix the class name properly, and manually include the file it is in.
Once you have that, you need to register each root namespace. Sub-namespaces will work automatically.
Here is how we would register our “fun” namespace:
<?php // instantiate the loader $loader = new \slug_autoloader // register the "fun" namespace //we are assuming that the root namespace is in "src", a subdir of the current directory. $loader->addNamespace('fun', dirname( __FILE__ ) . '/src' ); // register the autoloader $loader->register();
Keep in mind that there is no need to use more than one autoloader on a site. If you are doing full-site development, with careful planning you can share them between multiple, purpose-specific plugins.
That’s all it takes
In this article, I showed you how to use a class autoloader, following established PHP community standards in your WordPress plugin, theme or, even for a full site. Whether you add your own, or use Composer’s, it’s an easy thing to do. It really does make life a lot easier when you use one. Also, understanding how the standards work makes it easier to work with third-party PHP libraries.
3 Comments