[RFC] Function autoloading through spl_autoload*

php.internals

Ferenc Kovacs

15 years ago
Hi. I would like to introduce this RFC which would provide function autoloading through the spl_autoload facility without userland BC breakage. https://wiki.php.net/rfc/autofunc
-- Ferenc Kovács @Tyr43l - http://tyrael.hu

Ryan McCue

15 years ago
Ferenc Kovacs wrote:
> I would like to introduce this RFC which would provide function > autoloading through the spl_autoload facility without userland BC > breakage.
Shouldn't the default type be T_CLASS|T_INTERFACE?
-- Ryan McCue <http://ryanmccue.info/>

Ferenc Kovacs

15 years ago
On Sat, Aug 6, 2011 at 2:24 PM, Ryan McCue <lists@rotorised.com> wrote:
> Ferenc Kovacs wrote: >> I would like to introduce this RFC which would provide function >> autoloading through the spl_autoload facility without userland BC >> breakage. > > Shouldn't the default type be T_CLASS|T_INTERFACE? >
sorry for the late reply. judging from your reply and the conversion on irc with Etienne, I think that the usage of the token constants are ambiguous(we have different token constants for classes and interfaces as you mentioned for example). originally I chose this because this would be fully backward compatible, but now I think that we should add new constants. what do you think?
-- Ferenc Kovács @Tyr43l - http://tyrael.hu

Sebastian Krebs

15 years ago
Hi, 2011/8/12 Ferenc Kovacs <tyra3l@gmail.com>
> On Sat, Aug 6, 2011 at 2:24 PM, Ryan McCue <lists@rotorised.com> wrote: > > Ferenc Kovacs wrote: > >> I would like to introduce this RFC which would provide function > >> autoloading through the spl_autoload facility without userland BC > >> breakage. > > > > Shouldn't the default type be T_CLASS|T_INTERFACE? > > > > sorry for the late reply. > judging from your reply and the conversion on irc with Etienne, I > think that the usage of the token constants are ambiguous(we have > different token constants for classes and interfaces as you mentioned > for example). > originally I chose this because this would be fully backward > compatible, but now I think that we should add new constants. > what do you think? >
From the users point of view I don't care. It's just another constant. Also constants like SPL_AUTOLOAD_CLASS SPL_AUTOLOAD_FUNCTION SPL_AUTOLOAD_CONSTANT seems to be more obvious, because it reflects, that it belongs to spl-autoload.

Ferenc Kovacs

15 years ago
On Fri, Aug 12, 2011 at 12:12 PM, Sebastian Krebs <krebs.seb@googlemail.com> wrote:
> Hi, > > 2011/8/12 Ferenc Kovacs <tyra3l@gmail.com> > >> On Sat, Aug 6, 2011 at 2:24 PM, Ryan McCue <lists@rotorised.com> wrote: >> > Ferenc Kovacs wrote: >> >> I would like to introduce this RFC which would provide function >> >> autoloading through the spl_autoload facility without userland BC >> >> breakage. >> > >> > Shouldn't the default type be T_CLASS|T_INTERFACE? >> > >> >> sorry for the late reply. >> judging from your reply and the conversion on irc with Etienne, I >> think that the usage of the token constants are ambiguous(we have >> different token constants for classes and interfaces as you mentioned >> for example). >> originally I chose this because this would be fully backward >> compatible, but now I think that we should add new constants. >> what do you think? >> > > From the users point of view I don't care. It's just another constant. Also > constants like > > SPL_AUTOLOAD_CLASS > SPL_AUTOLOAD_FUNCTION > SPL_AUTOLOAD_CONSTANT > > seems to be more obvious, because it reflects, that it belongs to > spl-autoload. >
imo from the users point of view your suggested constant names are much better, plus the T_* constants are provided by the tokenizer extension, which AFAK could be disabled compilation time, and by itself would be a bad idea to couple the two extension. so +1 for your suggestion, I will update the RFC, and check out how hard would be to create a patch.
-- Ferenc Kovács @Tyr43l - http://tyrael.hu

Jan Dolecek

15 years ago
Someone said that it won't be that easy, because functions are searched within a namespace first and when they don't exist there, then are called from global namespace. Example: <?php namespace example; echo substr('Test', 1, 1); When calling function substr, Zend engine first tries to find function example\substr. If such function doesn't exist, it tries just substr which is found and called. Thanks to this lookup, we don't need to escape all function calls with backslash prefix. <?php echo not_found(1); When trying to autoload a function, which one should be auto loaded? "example\not_found" or "not_found"? Similar situation is with constants, because of BC a non-existing constant must result in string with the same value as constant's name. <?php var_dump(MY_CONSTANT); // string(11) "MY_CONSTANT" Some programmes rely on it (though it's not recommended) and calling autoloader everytime would add significant load to such apps. Jan Dolecek juzna.cz@gmail.com On Fri, Aug 12, 2011 at 11:31 AM, Ferenc Kovacs <tyra3l@gmail.com> wrote:

Sebastian Krebs

15 years ago
Am 12.08.2011 15:54, schrieb Jan Dolecek:
> Someone said that it won't be that easy, because functions are > searched within a namespace first and when they don't exist there, > then are called from global namespace. > > Example: > <?php > namespace example; > echo substr('Test', 1, 1); > > When calling function substr, Zend engine first tries to find function > example\substr. If such function doesn't exist, it tries just substr > which is found and called. Thanks to this lookup, we don't need to > escape all function calls with backslash prefix. > > <?php > echo not_found(1); > When trying to autoload a function, which one should be auto loaded? > "example\not_found" or "not_found"?
Whats about "both"? - Does <namespace>\<function> exists? - Does \<function> exists? Till here everything is like usual - Try to load <namespace>\<function>. Does <namespace>\<function> exists? - Try to load \<function>. Does \<function> exists? I make two additional assumptions: 1. Like PSR-0 developers may get used to put their functions into namespaces, thus custom functions usually get loaded in the first "autoload-step" 2. I don't think anybody will use one-function-per-file, thus (lets say) every function from one namespace is loaded at once.
> Similar situation is with constants, because of BC a non-existing > constant must result in string with the same value as constant's name. > <?php > var_dump(MY_CONSTANT); // string(11) "MY_CONSTANT" > > Some programmes rely on it (though it's not recommended) and calling > autoloader everytime would add significant load to such apps.
In my opinion code, that _relies_ on this should be treated as "unstable" anyway. I don't think it's very useful to take care of bad habits and also I don't think it's useful to accept/decline features/enhancements, because there are convenience/fallback-features, that were _never_ recommended. Also it's even not a bc-break, because it works. And however: There is a very easy workaround: | define('MY_CONSTANT', 'MY_CONSTANT'); ;)

Ferenc Kovacs

15 years ago
On Fri, Aug 12, 2011 at 3:54 PM, Jan Dolecek <juzna.cz@gmail.com> wrote:
> Someone said that it won't be that easy, because functions are > searched within a namespace first and when they don't exist there, > then are called from global namespace. > > Example: > <?php > namespace example; > echo substr('Test', 1, 1); > > When calling function substr, Zend engine first tries to find function > example\substr. If such function doesn't exist, it tries just substr > which is found and called. Thanks to this lookup, we don't need to > escape all function calls with backslash prefix. > > <?php > echo not_found(1); > When trying to autoload a function, which one should be auto loaded? > "example\not_found" or "not_found"?
first example\not_found then \not_found if necessary.
> > > > Similar situation is with constants, because of BC a non-existing > constant must result in string with the same value as constant's name. > <?php > var_dump(MY_CONSTANT); // string(11) "MY_CONSTANT" > > Some programmes rely on it (though it's not recommended) and calling > autoloader everytime would add significant load to such apps. >
the autoloader shouldn't affect this, if no const is found, then the constname should be used.
-- Ferenc Kovács @Tyr43l - http://tyrael.hu

Sebastian Krebs

15 years ago
Hi. I really like to see this [1] and also I would like to see this in 5.4. I cannot C, thus I would appreciate, if someone can provide a patch. Additional I suggests to include constants (global/namespace, not the class constants) into the RFC too. [1] http://news.php.net/php.internals/54196 Am 06.08.2011 13:15, schrieb Ferenc Kovacs:

Derick Rethans

15 years ago
On Sat, 6 Aug 2011, Ferenc Kovacs wrote:
> I would like to introduce this RFC which would provide function > autoloading through the spl_autoload facility without userland BC > breakage. > > https://wiki.php.net/rfc/autofunc
I understand the proposal, but I don't see any compelling reasons in the RFC of why we actually need autoloading for functions? For classes it makes sense because there is almost always a class to file mapping. For functions (and constants) that is not the case, so I am wondering how useful this function autoloading actually is. cheers, Derick
-- http://derickrethans.nl | http://xdebug.org Like Xdebug? Consider a donation: http://xdebug.org/donate.php twitter: @derickr and @xdebug

Nikita Popov

15 years ago
On Sun, Aug 14, 2011 at 3:55 PM, Derick Rethans <derick@php.net> wrote:
> I understand the proposal, but I don't see any compelling reasons in the > RFC of why we actually need autoloading for functions? For classes it > makes sense because there is almost always a class to file mapping. For > functions (and constants) that is not the case, so I am wondering how > useful this function autoloading actually is.
As Sebastian already mentioned, if all functions in a namespace are grouped into one file, it would be simple to load that file using such a concept.

Stas Malyshev

15 years ago
Hi! On 8/14/11 7:02 AM, Nikita Popov wrote:
> As Sebastian already mentioned, if all functions in a namespace are > grouped into one file, it would be simple to load that file using such > a concept.
Why wouldn't you just use a class?
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Sebastian Krebs

15 years ago
Hi, Am 14.08.2011 20:17, schrieb Stas Malyshev:
> Hi! > > On 8/14/11 7:02 AM, Nikita Popov wrote: >> As Sebastian already mentioned, if all functions in a namespace are >> grouped into one file, it would be simple to load that file using such >> a concept. > > Why wouldn't you just use a class?
Counterquestion: Why shouldn't I use functions? They exists, they are official supported, they are neither marked as deprecated, nor ever discussed to get removed at all. It feels a little bit weird to me, that I need to explain, why one wants to use functions, that are part of the language since ever. And (on the other hand) static methods are imo just something different. Regards, Sebastian

Stas Malyshev

15 years ago
Hi! On 8/14/11 1:39 PM, Sebastian Krebs wrote:
> Counterquestion: Why shouldn't I use functions? They exists, they are
Because if you want to use functions of similar nature organized in a package, that's what classes are used for. You want to do something that goes contrary to how language is designed and then you want language to change to fit your wrong usage. I don't see how it's good for the language.
> discussed to get removed at all. It feels a little bit weird to me, that > I need to explain, why one wants to use functions, that are part of the
Please don't distort my words - nobody asked you why you need to use functions in general. I asked why you don't use mechanisms for grouping functions that exist in the language and work just fine with existing semantics and instead want new semantics that has its own problems.
> language since ever. And (on the other hand) static methods are imo just > something different.
How different?
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Sebastian Krebs

15 years ago
Hi, Am 14.08.2011 23:06, schrieb Stas Malyshev:
> Hi! > > On 8/14/11 1:39 PM, Sebastian Krebs wrote: >> Counterquestion: Why shouldn't I use functions? They exists, they are > > Because if you want to use functions of similar nature organized in a > package, that's what classes are used for.
When I must use classes are for packaging functions (that aren't functions anymore, when I make methods out of them), what are namespaces for? I'm just curious ^^
> You want to do something that > goes contrary to how language is designed and then you want language to > change to fit your wrong usage. I don't see how it's good for the language.
I just want to use functions. Whats wrong with that? Really: Thats all.
>> discussed to get removed at all. It feels a little bit weird to me, that >> I need to explain, why one wants to use functions, that are part of the > > Please don't distort my words - nobody asked you why you need to use > functions in general. I asked why you don't use mechanisms for grouping > functions that exist in the language and work just fine with existing > semantics and instead want new semantics that has its own problems.
Its not (only) about grouping functions, its about using custom functions at all. Grouping things is always a good idea and with namespaces (not classes) it is already possible in a very clean and easy way. There is no need to misuse OOP for that. As far as I can see there is absolutely nothing new here. That functions/constants should be covered by autoloading is the only thing I would like to see in one future release.
>> language since ever. And (on the other hand) static methods are imo just >> something different. > > How different?
Static methods are (static) methods and functions are functions. Classes can get extended [1] and have a state and such. In short: Both methods and functions come from two different paradigms (OOP and procedural/functional). Just saying "static methods are just grouped functions" is a little bit to less and will always feel like a hack to me. PHP calls itself "multiparadigm", but the prodecural part feels very neglected over the time. Regards, Sebastian [1] Yes, I know, I can mark a class as "final", but this keyword is imo the most useless keyword ever ;)

Stas Malyshev

15 years ago
Hi! On 8/14/11 2:50 PM, Sebastian Krebs wrote:
> I just want to use functions. Whats wrong with that? Really: Thats all.
Nothing at all. But changing semantics of the language because somebody doesn't want to use existing semantics doesn't look like a good idea to me. PHP has means to do what you want to do. If you don't want to use them - well, that's your decision.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Sebastian Krebs

15 years ago
Hi, Am 15.08.2011 02:37, schrieb Stas Malyshev:
> Hi! > > On 8/14/11 2:50 PM, Sebastian Krebs wrote: >> I just want to use functions. Whats wrong with that? Really: Thats all. > > Nothing at all. But changing semantics of the language because somebody > doesn't want to use existing semantics doesn't look like a good idea to > me. PHP has means to do what you want to do. If you don't want to use > them - well, that's your decision.
Now I'm getting a little bit confused: About which new/changing semantics you are talking about? I want to use custom functions, that exists, since the language itself exists, but I want to get rid of unnecessary `[include|require]_once()`-calls. I really don't see _any_ new semantics here. Regards, Sebastian

Stas Malyshev

15 years ago
Hi! On 8/14/11 9:35 PM, Sebastian Krebs wrote:
> Now I'm getting a little bit confused: About which new/changing > semantics you are talking about? I want to use custom functions, that > exists, since the language itself exists, but I want to get rid of > unnecessary `[include|require]_once()`-calls.
You want to change how autoloader works. This would also be a problem with global function callback for namespaces (http://www.php.net/manual/en/language.namespaces.fallback.php) since each call to, say, strlen would produce an autoloader call.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Sebastian Krebs

15 years ago
Hi, Am 14.08.2011 15:55, schrieb Derick Rethans:
> On Sat, 6 Aug 2011, Ferenc Kovacs wrote: > >> I would like to introduce this RFC which would provide function >> autoloading through the spl_autoload facility without userland BC >> breakage. >> >> https://wiki.php.net/rfc/autofunc > > I understand the proposal, but I don't see any compelling reasons in the > RFC of why we actually need autoloading for functions?
For the same reasons, why class-autoloading is useful: Loading when needed and avoiding unnecessary repetitive include-statements.
> For classes it > makes sense because there is almost always a class to file mapping. For > functions (and constants) that is not the case, so I am wondering how > useful this function autoloading actually is.
Like classes there may be also a function-to-filename-mapping, especially now, since namespaces exists. It is very easy to extend the PSR-0 standard (lets say: PSR-0.1 ;)) so functions and constants are covered by it too: - Constants and functions are in a file named after the namespace myNamespace\foo\bar => MyNamespace/foo/bar.php When class-autoloading were introduced there were no ^real^ class-to-file-mapping too. You had to define it yourself the time, when you wrote your `__autoload()`-function. It's nearly the same with functions/constants now, except that we are away from a single function and that there are already ideas, that may cover such mappings already. Or in my words: I don't see _any_ reason, why function-/constant-autoloading does _not_ exists ;)
> > cheers, > Derick >
Regards, Sebastian

Matthew Weier O'Phinney

15 years ago
On 2011-08-14, Derick Rethans <derick@php.net> wrote:
> On Sat, 6 Aug 2011, Ferenc Kovacs wrote: > > I would like to introduce this RFC which would provide function > > autoloading through the spl_autoload facility without userland BC > > breakage. > > > > https://wiki.php.net/rfc/autofunc > > I understand the proposal, but I don't see any compelling reasons in the > RFC of why we actually need autoloading for functions? For classes it > makes sense because there is almost always a class to file mapping. For > functions (and constants) that is not the case, so I am wondering how > useful this function autoloading actually is.
Namespaces support the following code types: * Constants * Functions * Classes and Interfaces Currently, autoloading in PHP allows us to dynamically identify and load only classes and interfaces. However, not all code is written using OOP. If a developer doesn't want to dive into include/require(_once) hell in order to use their namespaced functions and/or constants, they have no real options. As an example, let's say I've created a procedural CMS or blog of some sort. In there, I have a file like this: <?php namespace MyProjectName\Posts; $entries = getEntries(date('Y')); foreach ($entries as $entry) { displayEntrySummary($entry); } Next, assume the "getEntries" and "displayEntriesSummary" functions are also in the namespace "MyProjectName\Posts". How does my code load those functions? Traditionally, we've used: include_once 'MyProjectName/Posts/functions.php'; or include_once __DIR__ . '/functions.php'; in our files. But why should we have to do that? Why are functions -- which make up the bulk of PHP's functionality, and which are the bread-and-butter of many PHP projects -- get second-class status when it comes to autoloading? I can see an autoloader like this: function autoloadFunctions($funcname, $type = SPL_AUTOLOAD_FUNCTION) { if (!strstr($funcname, '\\')) { // we won't deal with un-namespaced functions return false; } $namespace = substr($funcname, 0, strrpos($funcname, '\\')); $funcfile = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR . 'Functions.php'; return include_once($funcfile); } and that might autoload all functions in a given namespace. I've seen other projects that put a function per-file -- so those might become even more granular. Basically, I don't see why we _wouldn't_ want this functionality in PHP. It makes namespaces practical and useful for procedural applications.
-- Matthew Weier O'Phinney Project Lead | matthew@zend.com Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

Chris Stockton

15 years ago
Hello, On Mon, Aug 15, 2011 at 2:30 PM, Matthew Weier O'Phinney <weierophinney@php.net> wrote:
> On 2011-08-14, Derick Rethans <derick@php.net> wrote: >> On Sat, 6 Aug 2011, Ferenc Kovacs wrote: >> > I would like to introduce this RFC which would provide function >> > autoloading through the spl_autoload facility without userland BC >> > breakage. >> > >> > https://wiki.php.net/rfc/autofunc
I must say a few of the suggestions I have seen appear a bit odd, however I believe that the proposed RFC suggestion using SPL is perfectly in alignment with how I would expect auto-loading to work. This would be a nice feature to have for a lot of code bases I am sure. -Chris

Sebastian Krebs

15 years ago
Hi, With this mail I don't want to talk to anyone directly, but I just want to summarize the situation as far as I understand. --- - Autoloading constants --- No problem here: When the loading procedure fails, it gets converted to a string like before. It may be a performance impact, but the code, that relies on this "feature" gets flooded with warnings anyway. --- - Autoloading functions --- If I understood it right the only problem is, that *someFunction()* may be in the global, as well as in the current namespace. This means, the developer write a function in a namespace, that already exists in the global scope, which remains to feel quite scary to me. Its way more confusing, that (e.g.) *strpos()* don't behave, like expected and learned for years now. It will affect only single namespaces, because if you want to call a function from another namespace you must prefix it with a qualified or full-qualified namespace anyway. And last but not least: Currently you must include the files containing the functions yourself. This means, that existing code is _not_ affected, because as long as no one removes the include-statements, it even not call any autoloading. But when the developers decides to remove them, they probably wants to use the autoloading, what means, that they (hopefully) understand, how it works. However, in my opinion the important part is to just make a decision the sooner, the better, as long as there are not too much creepy code out there (I don't know any and I can't imagine, that there is). Because functions with namespace are quite unhandy without autoloading and I don't think, that there is much use of it. So the 2 possible solutions: 1: - test namespace - test global - load namespace - load global 2: - test namespace - load namespace - test global - load global Maybe 3: - test namespace - test global - load global - load namespace would be a solution too, but it seems a little bit curious, when I use namespaces, but it looks into the global scope first. Regards, Sebastian Am 06.08.2011 13:15, schrieb Ferenc Kovacs:

Etienne Kneuss

15 years ago
Hi, On Thu, Aug 18, 2011 at 00:15, Sebastian Krebs <krebs.seb@googlemail.com> wrote:
> Hi, > > With this mail I don't want to talk to anyone directly, but I just want to > summarize the situation as far as I understand. > > > --- > - Autoloading constants > --- > No problem here: When the loading procedure fails, it gets converted to a > string like before. It may be a performance impact, but the code, that > relies on this "feature" gets flooded with warnings anyway. > > > > --- > - Autoloading functions > --- > If I understood it right the only problem is, that *someFunction()* may be > in the global, as well as in the current namespace. This means, the > developer write a function in a namespace, that already exists in the global > scope, which remains to feel quite scary to me. Its way more confusing, that > (e.g.) *strpos()* don't behave, like expected and learned for years now. > > It will affect only single namespaces, because if you want to call a > function from another namespace you must prefix it with a qualified or > full-qualified namespace anyway. > And last but not least: Currently you must include the files containing the > functions yourself. This means, that existing code is _not_ affected, > because as long as no one removes the include-statements, it even not call > any autoloading. But when the developers decides to remove them, they > probably wants to use the autoloading, what means, that they (hopefully) > understand, how it works. > > However, in my opinion the important part is to just make a decision the > sooner, the better, as long as there are not too much creepy code out there > (I don't know any and I can't imagine, that there is). Because functions > with namespace are quite unhandy without autoloading and I don't think, that > there is much use of it. > > So the 2 possible solutions: > > 1: > - test namespace > - test global > - load namespace > - load global > > 2: > - test namespace > - load namespace > - test global > - load global > >
Also: 4: - test namespace - test global - load namespace
> Maybe > 3: > - test namespace > - test global > - load global > - load namespace > would be a solution too, but it seems a little bit curious, when I use > namespaces, but it looks into the global scope first. > > Regards, > Sebastian > > Am 06.08.2011 13:15, schrieb Ferenc Kovacs: >> >> Hi. >> >> I would like to introduce this RFC which would provide function >> autoloading through the spl_autoload facility without userland BC >> breakage. >> >> https://wiki.php.net/rfc/autofunc >> > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- Etienne Kneuss http://www.colder.ch

Stas Malyshev

15 years ago
Hi! On 8/17/11 3:15 PM, Sebastian Krebs wrote:
> However, in my opinion the important part is to just make a decision the > sooner, the better, as long as there are not too much creepy code out > there (I don't know any and I can't imagine, that there is). Because > functions with namespace are quite unhandy without autoloading and I > don't think, that there is much use of it.
We already made the decision, when we introduced the namespaces and made the resolution order what it is now. And we considered all the variants and discussed all the arguments brought here back then.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Ferenc Kovacs

15 years ago
On Thu, Aug 18, 2011 at 7:19 PM, Stas Malyshev <smalyshev@sugarcrm.com> wrote:
> Hi! > > On 8/17/11 3:15 PM, Sebastian Krebs wrote: >> >> However, in my opinion the important part is to just make a decision the >> sooner, the better, as long as there are not too much creepy code out >> there (I don't know any and I can't imagine, that there is). Because >> functions with namespace are quite unhandy without autoloading and I >> don't think, that there is much use of it. > > We already made the decision, when we introduced the namespaces and made the > resolution order what it is now. And we considered all the variants and > discussed all the arguments brought here back then.
could you link the discussion about the function autoloading back then? I only found the namespace resolution discussion, but nothing about functions, except that they should fall back to the global namespace as we don't have/didn't have autoloaders for them.
-- Ferenc Kovács @Tyr43l - http://tyrael.hu