[wp-trac] [WordPress Trac] #60414: Core PHP autoloader proposal

WordPress Trac noreply at wordpress.org
Thu Jun 4 14:31:13 UTC 2026


#60414: Core PHP autoloader proposal
-------------------------------------+-------------------------------------
 Reporter:  aristath                 |       Owner:  (none)
     Type:  enhancement              |      Status:  new
 Priority:  normal                   |   Milestone:  Future Release
Component:  General                  |     Version:
 Severity:  normal                   |  Resolution:
 Keywords:  has-patch has-unit-      |     Focuses:  performance,
  tests early                        |  sustainability
-------------------------------------+-------------------------------------

Comment (by tha_sun):

 Hey everyone – I'm resurrecting this ticket at the Core working group
 during Contributor Day at WordCamp Europe 2025 in Kraków.

 The updated PR is available at https://github.com/WordPress/wordpress-
 develop/pull/12089

 **Motivation and scope**

 The primary motivation is bootstrap performance. On large-scale, high-
 traffic sites I have implemented custom front controllers that strip
 unnecessary file includes from the default bootstrap reduce response times
 by 500ms or more on AJAX and REST API requests — code paths that never use
 90% of the classes WordPress eagerly requires. A native classmap
 autoloader in core eliminates that overhead without requiring site-
 specific hacks, and provides the infrastructure for further lazy-loading
 improvements downstream.

 I support the intentionally minimal scope to maximize the chance of
 acceptance:

 - A single `WP_Autoload` class with a static classmap (no Composer, no
 file-system scanning, no PSR-4 magic).
 - Only files that are *purely* class/interface/trait definitions — no side
 effects — are moved to the classmap. Files with procedural code at the top
 level are explicitly excluded.
 - The autoloader is registered at each bootstrap entry point; the class
 file itself is a pure definition with no side effects on include.

 **Changes from the original PR**

 Two entries have been *reverted* from the classmap compared to the
 original PR because the respective files contain non-class code that must
 execute at include time:

 - `class-wpdb.php` defines the global constants `OBJECT`, `ARRAY_A`,
 `ARRAY_N` etc. at file scope. It is loaded explicitly inside
 `require_wp_db()` in `load.php`, as trunk does.
 - `class-wp-importer.php` defines the global function `get_cli_args()`
 outside the class body. The explicit `require_once` is restored in `wp-
 admin/includes/import.php`.

 Both exclusions are documented in the `WP_Autoload` file docblock, along
 with the list of multi-class files (e.g. `class-json.php`) that require
 `require_once` semantics in the autoloader dispatch.

 The autoloader itself now uses `require_once` (rather than `require`) in
 `autoload_core()` specifically because some files in the classmap define
 more than one class — `class-json.php` defines `Services_JSON` and
 `Services_JSON_Error`, for example. Using `require_once` avoids a fatal
 "Cannot redeclare class" error if PHP attempts to load such a file a
 second time when resolving the second class name.

 New classes introduced in trunk since the original PR — the Abilities API,
 AI client adapters, connectors, icons registry, speculation rules, URL
 pattern prefixer, and the new REST endpoints — have been added to the
 classmap.

 **Two minor issues noted during the rebase, outside the scope of this
 PR:**

 - `src/wp-includes/class-IXR.php` is now effectively a no-op: the IXR
 classes are in the classmap and load individually. It should probably
 carry a `_deprecated_file()` call, as `class-feed.php` already does.
 - The guard in `src/wp-includes/plugin.php` that manually requires `class-
 wp-hook.php` and `class-wp-filter-sentinel.php` when the autoloader is
 absent (`if ( ! class_exists( 'WP_Autoload' ) )`) is retained as-is.
 `plugin.php` can be loaded in lightweight testing and mocking contexts
 (WP_Mock etc.) without a full WordPress bootstrap, so the defensive
 fallback is intentional even if it looks out of place.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/60414#comment:49>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list