Proposal: Implement a PHP autoloader in WordPress Core

Past discussions

8 years ago, a ticket was created in WordPress, suggesting a PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher autoloader for WordPress CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. classes. In that ticketticket Created for both bug reports and feature development on the bug tracker., many things were discussed regarding the concept of adding a PHP autoloader in WordPress. That ticket discusses adding an APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. to allow pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party developers to register their own classes, it discusses using Composer, as well as other more nuanced topics of implementing an autoloader in WP.

It is a long thread, but a recommended read for anyone wanting to get some more context and historical data. That initial discussion was derailed several times, so for the purposes of this proposal, a new ticket was created on #60414

Since then, a lot of things have changed – both in PHP and in WordPress. Despite all these changes, WordPress Core still loads most of its codebase on each page load – regardless of whether a file is used or not. That means that WordPress takes more time to load, and at the same time consumes more memory than it should.

The time cost of including these extra files is pretty small (almost negligible), but the memory cost is not – especially for small sites running on shared hosting. By including files that are never used on a page load, we’re forcing servers to keep them in-memory, which is obviously sub-optimal.

Current work

In 2022, work started in a pull request to implement a PHP autoloader for Core classes. In the 20 months since the PR was initially created, it has received feedback, has been polished, and has been tested thoroughly. It has been kept up-to-date with the trunktrunk A directory in Subversion containing the latest development code in preparation for the next major release cycle. If you are running "trunk", then you are on the latest revision. version of WordPress and is ready for production.

Initial tests show an improvement in loading time, CPU resources and memory consumption. On average, the improvements server-side for a new WP site with no plugins installed and using the default theme, are approximately 2-3ms for load-time, 0.5-1.5% for CPU time and 5-7% for memory consumption.

What the proposed implementation does

The implementation in that pull-request was kept simple and minimal:

  • Introduced a WP_Autoload class.
  • Added a CONST in the object, containing the classMap for classes & their filenames. A hardcoded classMap was deemed preferable because of legacy reasons. WordPress classes don’t (currently) have namespaces or standardized mapping. By using a hardcoded classMap we can introduce an autoloader, and facilitate future implementations & standardization.
  • Removed the include/require/include_once/require_once calls for files containing classes throughout the WP codebase
  • Included external libraries and their respective autoloaders in the Core autoloader.

What the proposed implementation does not do:

It does not introduce an API for plugins

The implementation does not introduce an API to allow plugins/themes to add their own classes to the autoloader. Instead, it only focuses on Core classes, keeping things minimal.

Though adding an API and/or method to allow plugins to add their classes to a centralized autoloader is something we can consider for the future, it is not a requirement for this initial implementation, and it would overcomplicate the initial steps of autoloading Core.

It does not use Composer

Since the Composer vs non-composer autoloader was one of the main points of discussion in the 8-year-old ticket, it’s worth mentioning here, and clarify some points:

Composer is a very mature and safe way to autoload classes. However, this initial implementation does not use it.

This proposal is for a minimally invasive, performance-optimized change. It implements autoloading using a hardcoded classMap. Still, It does take care of all the preliminary work so if it is decided that a Composer autoloader is what we want to do, then switching to that will be a relatively easy task. The current PR has a very narrow focus and serves as the first step towards modernizing the WP codebase.

Composer would allow us to automate generating the autoloader, so if deemed appropriate, we could modify the current proposal to implement that.

Adding an initial, minimal autoloader will not blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. a future Composer implementation. It is easier to start without it, and then add it if we find that we need it. Doing the reverse could prove more difficult, so this path was deemed safer as a first step.

Benefits

The result of that PR is a cleaner and faster codebase. But this change is not only beneficial to Core developers, it will also benefit the ecosystem as a whole:

  • Reduce friction for plugin developers: Right now, plugin developers usually need to check if a class exists, if it doesn’t then look up its location in Core files, include the file etc. Then and only then can they safely use what WP has to offer. Adding an autoloader makes things easier and removes a friction point for plugin developers who will now be able to directly use a WP class.
  • Improved performance: – no matter how small the improvement is, it can make a big difference for hosts and larger sites.
  • This is the first step towards modernizing the WP codebase. Though in itself it may appear like a marginal (but still very worthy) performance improvement, it opens the door to more improvements in the future of WordPress without any backwards-compatibility concerns.

A word about overriding Core classes

One concern has already been raised, and I want to immediately tackle it: adding an autoloader for WordPress Core classes would mean that it will be possible to override these classes by loading another file early enough. We should not base code decisions in Core on how developers might misuse it… There are always ways that someone can mess up WordPress by doing the wrong thing. Being able to override Core classes can be seen both a pro and a con, depending on our point of view – but should not be a deciding factor.

  • It can benefit hosts who need to override things because of idiosyncracies in their hosting environment.
  • It can benefit site-builders who don’t know any better and are currently “hacking” Core files, making it impossible to later apply security updates. As WP purists, we know not to ever do that, but we can’t assume that everyone else is as mindful as we are.
  • It is a shift in the way we think about WP classes, and change is not easy. Autoloading classes is a battle-tested and established good practice in all modern applications.
  • When adding a new class file to WP-Core, we’ll need to update the classMap accordingly. This is not a big issue however, since we won’t have to include the files we add – just add them to the class-map.

Adding a PHP autoloader to WordPress is a relatively trivial change as the PR demonstrates. It comes with nice benefits and modernizes the way we handle class loading. Because it also represents a fundamental change in the way we include files and classes in the future, your feedback would be greatly appreciated.

Props @joostdevalk for the review