Le 16/07/2026 à 06:25, fennic log a écrit :
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
-----
I don't really see the advantage of having "spl_autoload_psr4_enable"
and "spl_autoload_psr4_enabled" functions: since there's a new
"spl_autoload_psr4_register" function, it means the feature should be
enabled by default, but registering PSR-4 namespaces is still opt-in.
Composer's autoloader might evolve in time to use it, but it can
internally detect PHP's version and dump the same autoloader as today
for current PHP versions, and dump a "new" autoloader for PHP versions
using built-in PSR-4 autoloading.
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.
If you're using Composer, built-in PSR-4 autoloading is a good start,
but in the end it won't be enough: Composer still supports PSR-0, and
supports custom files and classmaps. Adding built-in support for PSR-0
isn't necessarily useful (since it's supposed to have been deprecated
for a long time now), but custom classmaps could be interesting. A
function "spl_register_classmap_autoload(array $classmap, bool $prepend
= false)" function (or for single registrations with "string $class,
string $filepath" instead of an array, whatever) could also be used by
Composer in the future.
And by extrapolating, we can have more functions to replace the process
Composer goes on when generating a classmap with the "-o / --optimize"
option in the "dump-autoload" command and make the first run of a
process handling generate the classmap for certain registered psr4
namespaces and put them in cache (opcache, memcache, apcu...) (something
like "generate_psr4_classmap(string $nsPrefix)", or with the cache
backend's name like "opcache_generate_classmap_from_psr4(string
$nsPrefix)" ), so that further executions "just" fetch this classmap
cache from memory, thus enhancing built-in PSR-4 autoloading (just like
Composer's, but built-in, and classmap stored natively in memory instead
of the generated classmap file being stored in opcache and having to be
re-run). Benchmarks would be needed to check if built-in classmap would
be better than Composer's (so it implies a cache backend to check if
re-running the generated classmap is slower or not than a built-in
memory hashmap of classes and files), but it's feasible.
WDYT? Should an extrapolation of your suggestion make it to the core
too? (I personally think it should, either with this first RFC or with
further RFCs once this one is accepted)