[Pre-RFC][Discussion] Native Engine-Level PSR-4 Autoloader

From: Date: Thu, 16 Jul 2026 04:25:34 +0000
Subject: [Pre-RFC][Discussion] Native Engine-Level PSR-4 Autoloader
Groups: php.internals 
Request: Send a blank email to internals+get-131956@lists.php.net to get a copy of this message
PSR-4 has been the community standard for autoloading namespaced classes since 2014 and is used by virtually every modern PHP package via Composer. However, the actual autoloading still requires userspace code: spl_autoload_register() with a closure or class method (almost always generated by Composer) that performs prefix matching and file_exists/require. This RFC proposes adding a small set of native functions that allow the engine itself to perform PSR-4 autoloading directly from registered prefix → base directory mappings. Package managers and applications can opt into the faster, engine-native path instead of (or in addition to) registering a userspace callback. With emphasis on PSR-4 compliance, the engine implementation MUST follow the PSR-4 specification exactly for prefix matching, relative path construction, file extension (.php), and case sensitivity of the terminating class name. This can provide a performance improvement for PSR-4 heavy workloads by eliminating userspace callback overhead. To fully support PSR-4 autoloading I would propose a function spl_autoload_psr4_register and complimenting functions. Here is a proposed API. ```PHP /** * Register a PSR-4 namespace prefix → base directory mapping for native engine autoloading. * * @param string $prefix Namespace prefix (trailing \ recommended; will be normalized) * @param string|array $baseDirs One base directory (string) or list of base directories (array) * @param bool $prepend Insert at front of search order (like spl_autoload_register) * @return bool True on success */ function spl_autoload_psr4_register(string $prefix, string|array $baseDirs, bool $prepend = false): bool {} /** * Remove a previously registered PSR-4 prefix (and its base directories). */ function spl_autoload_psr4_unregister(string $prefix): bool {} /** * Enable/disable the native PSR-4 fast path. When disabled, mappings are kept but ignored. */ function spl_autoload_psr4_enable(bool $enable = true): void {} /** * Whether the native PSR-4 mechanism is currently active. */ function spl_autoload_psr4_enabled(): bool {} /** * Return current mappings as [prefix => [baseDir, ...], ...] preserving registration order. */ function spl_autoload_psr4_get_mappings(): array {} ``` There would be no backwards compatibility issues and a simple function_exists('spl_autoload_psr4_register') call would be used to trigger use of the new functionality or fallback to userland callback register. Discussion points: Should there be an spl_autoload_psr4_enable(bool) function to enable this functionality or should the usage of spl_autoload_psr4_register auto-enable the autoloader? References - PSR-4 Specification: https://www.php-fig.org/psr/psr-4/ - PSR-4 Example Implementations: https://www.php-fig.org/psr/psr-4/examples/ - Old related RFC: https://wiki.php.net/rfc/splclassloader (declined, PSR-0 focused) - Composer Autoloader class: https://github.com/composer/composer/blob/main/src/Composer/Autoload/ClassLoader.php ----- This idea originally spawned from my idea to try an eliminate the standard bootstrapping call of `include_once(__DIR__ . '/vendor/autoload.php')` While this does not achieve this, i believe it can be a good first step.

« previous php.internals (#131956) next »