Re: [RFC] New core autoloading mec hanism with support for function autoloading
| From: | Rowan Tommins | Date: | Tue, 11 Apr 2023 08:48:20 +0000 |
| Subject: | Re: [RFC] New core autoloading mec hanism with support for function autoloading | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-119900@lists.php.net to get a copy of this message | ||
On 10 April 2023 13:17:04 BST, "G. P. B." <george.banyard@gmail.com> wrote:
>Hello Internals,
>
>Dan and I would like to propose a new core autoloading mechanism that fixes
>some minor design issues with the current class autoloading mechanism and
>introduce a brand-new function autoloading mechanism:
>https://wiki.php.net/rfc/core-autoloading
Hi!
Thanks both for tackling this, I know function autoloading has long been on a lot of people's
wish lists.
A few thoughts:
> As a result of the pinning, function_exists() will return true for functions in namespaces that
> have been pinned to a global function.
The lookup pinning seems like the right way to optimise the implementation, but I don't think
it should be visible to user code like this - a lookup for "strlen" in namespace
"Foo" is not the same as defining the function "Foo\strlen". Consider this code:
namespace Bar {
if ( function_exists('Foo\strlen') ) {
\Foo\strlen('hello');
}
}
namespace Foo {
strlen('hello'); // triggers name pinning
}
namespace Bar {
if ( function_exists('Foo\strlen') ) {
\Foo\strlen('hello');
}
}
If I'm reading the RFC correctly, the second function_exists will return true. I'm less
clear if the call to \Foo\strlen will actually succeed - if it gives "undefined function",
then function_exists is clearly broken; if it calls the global strlen(), that's a very
surprising side effect. For bonus points, the call to strlen that triggers pinning could be inside
an autoloader, making even the first function_exists call return true.
Similarly, I think it should be possible to "unpin" a function lookup with a later
definition, even if no autoloading would be triggered. That is, this should not be a duplicate
definition error:
namespace Foo;
if ( strlen('magic') != 42 ) {
function strlen($string) { /* ... */ }
}
> The use of the word class in the API is currently accurate
This isn't actually true: classes, interfaces, traits, and enums all share a symbol table, and
thus an autoloader. I don't know of a good name for this symbol table, though.
Regarding the API, would it be possible to take advantage of nearly all autoloaders only being
interested in particular namespace prefixes?
Currently, every registered autoloader is run for every lookup, and most immediately check the input
for one or two prefixes, and return early if not matched. I suspect this design is largely because
autoloading came before namespaces, so the definition of "prefix" wasn't
well-defined, but going in and out of userland callbacks like this is presumably rather inefficient.
Perhaps the "register" functions should take an optional list of namespace prefixes, so
that the core implementation can do the string comparison, and only despatch to the userland code if
the requested class/function name matches.
Thanks again for working on this!
Regards,
--
Rowan Tommins
[IMSoP]