Skip to content
PHP News
Search
Declined PHP 8.6

Function Autoloading (mark 5)

Function autoloading modeled on class autoloading, with no cost to calls that resolve normally.

Implement Function Autoloading as described in this RFC?

Primary vote · 2/3 majority

2 Yes 11 No 1 abstain 15% approval

This poll has closed.

The primary vote closed on August 13, 2026, with 2 votes in favor, 11 against and 1 abstention, far short of the two-thirds it needed. Function autoloading is still not part of PHP, and a new attempt can't go to a vote until February 2027 unless it changes substantially.

Summary

PHP has autoloaded classes for over 20 years, but functions have never had the same treatment. If a library ships plain functions, they have to be loaded up front, usually through Composer's files list, whether a request uses them or not. That is a big part of why so many libraries wrap helpers in static methods instead.

This RFC, the fifth attempt at the idea since 2011, proposed copying class autoloading for functions.

How it would have worked

You register a loader. When PHP hits a function it can't find, it calls your loader with the fully qualified name, and the loader can require the file that defines it:

spl_autoload_register_function_loader(function (string $function): void {
    // Foo\Math\add lives in functions/Foo/Math/add.php
    $path = __DIR__ . '/functions/' . str_replace('\\', '/', $function) . '.php';

    if (is_file($path)) {
        require $path;
    }
});

echo \Foo\Math\add(2, 3); // loads the file on first use, then 5

Loaders only run when a lookup fails, so calls to functions that already exist cost nothing extra. Autoloading would also have kicked in for call_user_func(), is_callable(), callbacks passed to array_map() and friends, and Reflection.

The RFC added four functions: spl_autoload_register_function_loader(), spl_autoload_unregister_function_loader(), spl_autoload_function_loaders() and spl_autoload_call_function_loader(). It also gave function_exists() a second $autoload parameter that defaults to true, the same as class_exists().

The namespace catch

Unqualified function calls inside a namespace fall back to the global function of the same name, and that fallback happens before any loader would run. So a namespaced function that shadows a built-in never gets autoloaded:

namespace Foo;

// Foo\strlen() exists in a file the loader could load...
$len = strlen('bar'); // ...but this is PHP's strlen(), so 3

The fix is to import it with use function Foo\strlen;, or to use declare(strict_namespace=1) from the companion Strict Namespace Resolution RFC, which turns the global fallback off for a file. The author checked the top 1,000 Packagist packages and found only 8 call sites across 2 packages that would hit this.

What would have changed for existing code

With no loaders registered, nothing. The two visible changes were the four new global function names, and function_exists() calling your loaders before returning. That second one would have affected the common polyfill pattern if (! function_exists('foo')) { ... }, unless you passed false as the second argument.

Our coverage