[php-src] Issue #23232: is_callable('\::method') asks the autoloader for an empty class name

[email protected] (spawnia)
Newsgroups php.bugs
Message-ID <[email protected]>
Issue: https://github.com/php/php-src/issues/23232
Author: spawnia

### Description

`is_callable()` on a string of the form `'\::method'` asks the autoloader for the **empty class name**. The same string without the leading backslash, `'::method'`, does not autoload at all. A leading `\` only marks the name as fully qualified, so this asymmetry looks like a bug.

The following code:

```php
<?php
spl_autoload_register(function (string $class): void {
    echo "autoload: '$class'\n";
});

foreach (['::a', '\::a', '\Foo::a', 'Foo::a'] as $callable) {
    echo "is_callable(\"$callable\")\n";
    is_callable($callable);
}
```

Resulted in this output:

```
is_callable("::a")
is_callable("\::a")
autoload: ''
is_callable("\Foo::a")
autoload: 'Foo'
is_callable("Foo::a")
autoload: 'Foo'
```

But I expected this output instead:

```
is_callable("::a")
is_callable("\::a")
is_callable("\Foo::a")
autoload: 'Foo'
is_callable("Foo::a")
autoload: 'Foo'
```

Reproduced unchanged on 8.3.32, 8.4.24 and 8.5.9 (official `php:*-cli` images).

An empty class name can never resolve, so autoloading it is pure overhead — and it is observable overhead. Composer's `ClassLoader::findFileWithExtension()` does `$first = $class[0];`, which on `''` emits `Warning: Uninitialized string offset 0`. Any application that promotes warnings to exceptions (Laravel's `HandleExceptions`, for example) then fails.

We hit this in CI: Laravel's `Factory::expandAttributes()` calls `is_callable()` on every string attribute, and a randomly generated password starting with `\::` (about 1 in a million with Faker's `password()`) made unrelated tests error out with `ErrorException: Uninitialized string offset 0`. Fixes are also filed with [composer](https://github.com/composer/composer/pull/13031) and [laravel](https://github.com/laravel/framework/pull/61151), but the autoload request for `''` looks wrong regardless of who else guards against it.

I am happy to prepare a patch rejecting the empty class name before autoload if you agree this should change.

### PHP Version

```
PHP 8.3.32, 8.4.24, 8.5.9
```

### Operating System

Linux (official `php:8.3-cli`, `php:8.4-cli`, `php:8.5-cli` images)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.