[DRAFT] [RFC] Function autoloading

php.internals

Anthony Ferrara

13 years ago
All, I have created a new draft RFC implementing function and constant autoloading in master: https://wiki.php.net/rfc/function_autoloading All feedback is welcome. Thanks Anthony

Stas Malyshev

13 years ago
Hi!
> I have created a new draft RFC implementing function and constant > autoloading in master: > > https://wiki.php.net/rfc/function_autoloading > > All feedback is welcome.
I think it is an unnecessary complication. Classes fit autoloader paradigm nicely, since the usual pattern is one class per one file (actually recommended in PSR), so it is easy to establish one-to-one automatic mapping between classes and files (also recommended in the PSR). But for functions nobody does this. This means that to implement function autoloader one will need to have a complicated and fragile logic (since there's no way to ensure this logic would be in sync with actual content of files containing multiple functions). Moreover, since this replaces a simple hash lookup with additional two function calls (and also other operations included in those) everywhere in the engine, it will also have performance impact of one of the most frequently used operations in the engine - function calls - while providing absolutely no benefit for 100% of existing code and 99.99% of future code. Putting autoloading of different entities into one function makes very little sense to me - why would the same code load both classes and functions? How would it do that besides ugly switch that just stuffs two completely different logic pieces into one function for no reason? The example given in the RFC is certainly not what anybody would actually want their autoloaders to do, so I fail to see any case for doing it and for putting loading more than one entity into one function (that given that autoloading function would be desirable at all, which it still doesn't seem so for me). It is
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Stas Malyshev

13 years ago
Hi!
> It is
Oops, clicked too soon. I wanted to conclude that I think it is too many complications in the engine for too little gain.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Laruence

13 years ago
On Fri, Aug 30, 2013 at 12:58 PM, Stas Malyshev <smalyshev@sugarcrm.com> wrote:
> Hi! > >> It is > > Oops, clicked too soon. I wanted to conclude that I think it is too many > complications in the engine for too little gain.
I agree with Stas here. thanks
> -- > Stanislav Malyshev, Software Architect > SugarCRM: http://www.sugarcrm.com/ > (408)454-6900 ext. 227 > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >
-- Laruence Xinchen Hui http://www.laruence.com/

Sara Golemon

13 years ago
> I think it is an unnecessary complication. Classes fit autoloader > paradigm nicely, since the usual pattern is one class per one file > (actually recommended in PSR), so it is easy to establish one-to-one > automatic mapping between classes and files (also recommended in the > PSR). But for functions nobody does this. This means that to implement > function autoloader one will need to have a complicated and fragile > logic (since there's no way to ensure this logic would be in sync with > actual content of files containing multiple functions). > > I disagree on the basis that namespaced functions/constants *do* fit the
same autoloading paradigm. Moreover, since this replaces a simple hash lookup with additional two
> function calls (and also other operations included in those) everywhere > in the engine, it will also have performance impact of one of the most > frequently used operations in the engine - function calls - while > providing absolutely no benefit for 100% of existing code and 99.99% of > future code. > > Those function calls would only kick in if the function/constant wasn't
already defined, which will be the exception case, so perf isn't a strong argument.
> Putting autoloading of different entities into one function makes very > little sense to me - why would the same code load both classes and > functions? How would it do that besides ugly switch that just stuffs two > completely different logic pieces into one function for no reason? The > example given in the RFC is certainly not what anybody would actually > want their autoloaders to do, so I fail to see any case for doing it and > for putting loading more than one entity into one function (that given > that autoloading function would be desirable at all, which it still > doesn't seem so for me). > > That I agree with 100%.
-Sara

Stas Malyshev

13 years ago
Hi!
> I disagree on the basis that namespaced functions/constants *do* fit the > same autoloading paradigm.
If they're already namespaced, what prevents one to put it in a class and use good old PSR-compatible loading?
> Those function calls would only kick in if the function/constant wasn't > already defined, which will be the exception case, so perf isn't a > strong argument.
Not according to the code I see in the patch. There I see 2 func calls (among other things) before the hash is even looked up.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Sara Golemon

13 years ago
> If they're already namespaced, what prevents one to put it in a class > and use good old PSR-compatible loading? > > Nothing, really... Just countering your specific premise.
> > Those function calls would only kick in if the function/constant wasn't > > already defined, which will be the exception case, so perf isn't a > > strong argument. > > Not according to the code I see in the patch. There I see 2 func calls > (among other things) before the hash is even looked up. > > Well, the patch needs work obviously. I'm living in a magical world where
that's already been fixed. :) -Sara

Sebastian Krebs

13 years ago
2013/8/30 Stas Malyshev <smalyshev@sugarcrm.com>
> Hi! > > > I disagree on the basis that namespaced functions/constants *do* fit the > > same autoloading paradigm. > > If they're already namespaced, what prevents one to put it in a class > and use good old PSR-compatible loading? >
Well, static methods aren't the same as functions.
> > > Those function calls would only kick in if the function/constant wasn't > > already defined, which will be the exception case, so perf isn't a > > strong argument. > > Not according to the code I see in the patch. There I see 2 func calls > (among other things) before the hash is even looked up.
> -- > Stanislav Malyshev, Software Architect > SugarCRM: http://www.sugarcrm.com/ > (408)454-6900 ext. 227 > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- github.com/KingCrunch

Stas Malyshev

13 years ago
Hi!
> Well, static methods aren't the same as functions.
The big difference being?
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Nikita Popov

13 years ago
On Fri, Aug 30, 2013 at 7:10 PM, Stas Malyshev <smalyshev@sugarcrm.com>wrote:
> Hi! > > > Well, static methods aren't the same as functions. > > The big difference being? >
This seems to be the core of your argumentation in this thread: "Why don't you just use Foo::bar() instead of foo\bar()?" In which case, I wonder why we have functions at all. We could just use static methods instead after all. Maybe we should deprecate function support? On a more serious note: If you want an actual example of how functions can be easier to use than static methods, consider the "use function" RFC. Now that it's in, it is possible to directly import a function foo\bar() and use it with just bar(). Static methods allow no such thing. You always need to write the class name. The reason why people currently resort to using static methods instead of functions is the fact that there is no autoloading for functions. With autoloading, functions become a lot easier to use. Nikita

Stas Malyshev

13 years ago
Hi!
> This seems to be the core of your argumentation in this thread: "Why > don't you just use Foo::bar() instead of foo\bar()?" > > In which case, I wonder why we have functions at all. We could just use > static methods instead after all. Maybe we should deprecate function > support?
Maybe we should stop strawman arguments? I never claimed functions should be replaced with static methods or that we should deprecate anything, please don't put words in my mouth. What I claimed is that if you write code in a *specific pattern*, that is the only pattern that makes this proposal useful and that is, as far as I can see, in no way common among people that use functions, then *in this specific case* you could as well use slightly different pattern which would allow you to use existing facilities, and the only difference between the two is the word "class" and using :: instead of \.
> On a more serious note: If you want an actual example of how functions > can be easier to use than static methods, consider the "use function" > RFC. Now that it's in, it is possible to directly import a function > foo\bar() and use it with just bar(). Static methods allow no such > thing. You always need to write the class name.
Which is a good thing. Making different thing mean the same is not a good idea, it reduces readability. And typing 2 characters less was never a priority.
> The reason why people currently resort to using static methods instead > of functions is the fact that there is no autoloading for functions. > With autoloading, functions become a lot easier to use.
I don't accept this "resort to" - static functions is not something that one should "resort to", it is a completely valid syntactic construct.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Vartolomei Nicolae

13 years ago
So you say you will create a file for every function you want to support autoloading? As I already asked, tell us about realworld use case, for example where this could improve say big projects like Symfony or ZF. There is no logic to add this functionality just because we can. kindly, nvartolomei On Friday, August 30, 2013 at 8:38 PM, Nikita Popov wrote:

Sebastian Krebs

13 years ago
2013/8/31 Vartolomei Nicolae <nvartolomei@gmail.com>
> So you say you will create a file for every function you want to support > autoloading? >
I already _have_ create files for functions of a namespace... Closed source.
> As I already asked, tell us about realworld use case, for example where > this could improve say big projects like Symfony or ZF. >
Not everything can be found in the 5 most popular frameworks.
> There is no logic to add this functionality just because we can. >
The lack of logic is: Why is it actually missing? - Classes: Triggers an autoloader - Functions: Needs manual handling - Constants: Needs manual handling That is at first inconsistent. The need of "require_once"s is inefficient and error prone. Regards, Sebastian
> > > > kindly, > nvartolomei > > > On Friday, August 30, 2013 at 8:38 PM, Nikita Popov wrote: > > > On Fri, Aug 30, 2013 at 7:10 PM, Stas Malyshev <smalyshev@sugarcrm.com(mailto: > smalyshev@sugarcrm.com)>wrote: > > > > > Hi! > > > > > > > Well, static methods aren't the same as functions. > > > > > > The big difference being? > > > > This seems to be the core of your argumentation in this thread: "Why > don't > > you just use Foo::bar() instead of foo\bar()?" > > > > In which case, I wonder why we have functions at all. We could just use > > static methods instead after all. Maybe we should deprecate function > > support? > > > > On a more serious note: If you want an actual example of how functions > can > > be easier to use than static methods, consider the "use function" RFC. > Now > > that it's in, it is possible to directly import a function foo\bar() and > > use it with just bar(). Static methods allow no such thing. You always > need > > to write the class name. > > > > The reason why people currently resort to using static methods instead of > > functions is the fact that there is no autoloading for functions. With > > autoloading, functions become a lot easier to use. > > > > Nikita > > >
-- github.com/KingCrunch

Vartolomei Nicolae

13 years ago
On Saturday, August 31, 2013 at 9:03 PM, Sebastian Krebs wrote:
> I already _have_ create files for functions of a namespace... Closed source.
Can we take a look at them as an example? Maybe we can give you some advice how to refactor this code :)
> Not everything can be found in the 5 most popular frameworks.
Sure, but best practices usually are found there.
> The lack of logic is: Why is it actually missing?
Why humans don’t have one leg more, on head? I really want to look at an example for this. Looks like you are the only one who needs this. Oh, is OOP that bad for you? Also constant autoloading looks so bad, I want to see an example of this too for sure. Please don’t consider these questions like you need to prove something to me, I’m asking them hoping that anwers will help all internals to understand problem you are trying to solve. kindly, nvartolomei

Sebastian Krebs

13 years ago
2013/8/30 Stas Malyshev <smalyshev@sugarcrm.com>
> Hi! > > > Well, static methods aren't the same as functions. > > The big difference being? >
A function is stateless [1], a method isn't. A function operates only on the passed parameters [1], the method operates on the parameters and the context it inherits from the instance (non-static), or class (static and non-static). [1] Beside IO and "global variables"-hacks
> > -- > Stanislav Malyshev, Software Architect > SugarCRM: http://www.sugarcrm.com/ > (408)454-6900 ext. 227 >
-- github.com/KingCrunch

Stas Malyshev

13 years ago
Hi!
> A function is stateless [1], a method isn't. A function operates only on > the passed parameters [1], the method operates on the parameters and the > context it inherits from the instance (non-static), or class (static and > non-static).
Static method is stateless in the same meaning as unattached function is. Both can keep state in static variables if you wish. So no difference at all, public static method is just a namespaced function.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Zeev Suraski

13 years ago
> -----Original Message----- > From: Sebastian Krebs [mailto:krebs.seb@gmail.com] > Sent: Friday, August 30, 2013 9:02 PM > To: Stas Malyshev > Cc: Sara Golemon; Anthony Ferrara; internals@lists.php.net > Subject: Re: [PHP-DEV] [DRAFT] [RFC] Function autoloading > > 2013/8/30 Stas Malyshev <smalyshev@sugarcrm.com> > > > Hi! > > > > > Well, static methods aren't the same as functions. > > > > The big difference being? > > > > A function is stateless [1], a method isn't. A function operates only on
the
> passed parameters [1], the method operates on the parameters and the > context it inherits from the instance (non-static), or class (static and
non-
> static).
Static methods are equally stateless as global functions. A class state (static members) is no different from global variables (except for a tiny bit of lipstick in the form of encapsulation). There's no argument methods are different from global functions, not so with static methods which are essentially the same as global functions. Zeev

Daniel Macedo

13 years ago
I can accept not supporting PSR directly but implementing the class autoloader and stating "internals believes autoload in should exist, just doesn't specify/support any particular implementation", this makes sense, although I like PSR and don't really see others that make (as much) sense. This means internally we recognise an issue, resolve it in a general manner and allow some decisions up to the developer. Most of us developing now have the dreaded Utils class, it's an ugly hack filled with static methods... Yes, it might be almost the same as a namespaced bunch of classes, if you don't share states between those methods. Now consider this: PSR or any autoloader implementation allows for better sharing and code reuse; AND it makes sense to allow this for OOP as well as procedural code! I think Anthony and Nikki can see the forest from the trees, and that the core should support a number of use cases, not just what you currently use (and developers miss this functionality Anthony proposes) Having namespaced functions now allows for a function autoloader that uses the namespace as the file: awesome, great, let's do this! If not by looking at others code, or at Python, or at the Class/Constants/Namespaced-Functions all needing to have and being positively impacted by an autoloader... at least try and foresee the sense it makes for non-oop-but-maintained-by-smart-people to have an autoloader! Try to understand that this need exists and, it makes sense as a step into organising and refactoring legacy applications and for structure/grouping of classes, functions and constants, if only for the sake of organisation, but also for code-sharing, code reuse AND less managing of 20 *_once calls on top of every file in legacy applications! ;) Also as a bonus, a bunch of functions/constants filled files could got through a request never being read/included if never used, this alone should warrant pause!

Mark Tomlin

12 years ago
Daniel Macedo <admacedo@gmail.com> wrote:
> I can accept not supporting PSR directly but implementing the class > autoloader and stating "internals believes autoload in should exist, just > doesn't specify/support any particular implementation", this makes sense, > although I like PSR and don't really see others that make (as much) sense. > > This means internally we recognise an issue, resolve it in a general > manner and allow some decisions up to the developer. > > Most of us developing now have the dreaded Utils class, it's an ugly hack > filled with static methods... Yes, it might be almost the same as a > namespaced bunch of classes, if you don't share states between those methods. > > Now consider this: PSR or any autoloader implementation allows for better > sharing and code reuse; AND it makes sense to allow this for OOP as well > as procedural code! > > I think Anthony and Nikki can see the forest from the trees, and that the > core should support a number of use cases, not just what you currently > use (and developers miss this functionality Anthony proposes) > > Having namespaced functions now allows for a function autoloader that > uses the namespace as the file: awesome, great, let's do this! > > If not by looking at others code, or at Python, or at the > Class/Constants/Namespaced-Functions all needing to have and being > positively impacted by an autoloader... at least try and foresee the > sense it makes for non-oop-but-maintained-by-smart-people to have an autoloader! > > Try to understand that this need exists and, it makes sense as a step > into organising and refactoring legacy applications and for > structure/grouping of classes, functions and constants, if only for the > sake of organisation, but also for code-sharing, code reuse AND less > managing of 20 *_once calls on top of every file in legacy applications! ;) > > Also as a bonus, a bunch of functions/constants filled files could got > through a request never being read/included if never used, this alone should warrant pause!
From a user land developer, having the option of doing something is always better then not. You guys are doing a lot of great work for us mere mortals, why not also give us this option? It's been stated that thanks to a function short circuit that it would not cost performance and would add functionally. To me that seems like a win, win.
-- Thank You For Your Time.

Sebastian Krebs

13 years ago
2013/8/30 Stas Malyshev <smalyshev@sugarcrm.com>
> Hi! > > > I have created a new draft RFC implementing function and constant > > autoloading in master: > > > > https://wiki.php.net/rfc/function_autoloading > > > > All feedback is welcome. > > I think it is an unnecessary complication. Classes fit autoloader > paradigm nicely, since the usual pattern is one class per one file > (actually recommended in PSR), so it is easy to establish one-to-one > automatic mapping between classes and files (also recommended in the > PSR).
Autoloading was introduced long before PSR-0 and PSR-0 is also only a recommendation. So saying "class autoloading was easily introduceable, because there was _always_ a class<->file mapping" is somehow misleading.
> But for functions nobody does this. This means that to implement > function autoloader one will need to have a complicated and fragile > logic (since there's no way to ensure this logic would be in sync with > actual content of files containing multiple functions). >
This is the same complicated and fragile logik you need for class loading. For example compared to PSR-0 functions could be implemented in a file named after the namespace. An autoloader would be very similar to every already existing PSR-0 class loader.
> > Moreover, since this replaces a simple hash lookup with additional two > function calls (and also other operations included in those) everywhere > in the engine, it will also have performance impact of one of the most > frequently used operations in the engine - function calls - while > providing absolutely no benefit for 100% of existing code and 99.99% of > future code. > > Putting autoloading of different entities into one function makes very > little sense to me - why would the same code load both classes and > functions? How would it do that besides ugly switch that just stuffs two > completely different logic pieces into one function for no reason? The > example given in the RFC is certainly not what anybody would actually > want their autoloaders to do, so I fail to see any case for doing it and > for putting loading more than one entity into one function (that given > that autoloading function would be desirable at all, which it still > doesn't seem so for me).
> It is > -- > Stanislav Malyshev, Software Architect > SugarCRM: http://www.sugarcrm.com/ > (408)454-6900 ext. 227 > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- github.com/KingCrunch

Nikita Popov

13 years ago
On Fri, Aug 30, 2013 at 6:57 AM, Stas Malyshev <smalyshev@sugarcrm.com>wrote:
> I think it is an unnecessary complication. Classes fit autoloader > paradigm nicely, since the usual pattern is one class per one file > (actually recommended in PSR), so it is easy to establish one-to-one > automatic mapping between classes and files (also recommended in the > PSR). But for functions nobody does this. This means that to implement > function autoloader one will need to have a complicated and fragile > logic (since there's no way to ensure this logic would be in sync with > actual content of files containing multiple functions). >
For functions people do not commonly use a one-to-one mapping between a function name and a file, that's true. But there commonly *is* a one-to-one mapping between a *namespace* and a file. So if you have a function foo\bar\baz it will be in the file foo/bar.php (which defines all functions of namespace foo\bar). I think this is a rather common pattern in functional (or function-heavy) libraries and I use this myself too. Apart from such a namespace-to-file mapping you can also use the same approach some people use for classes: Just pregenerate the name-to-file mappings in an array, then loop up from there (e.g. theseer/autoload). This is one of the rare autoloading concepts that actually properly works in PHP (much unlike PSR-0, which fails to honor case-insensitivity).
> Moreover, since this replaces a simple hash lookup with additional two > function calls (and also other operations included in those) everywhere > in the engine, it will also have performance impact of one of the most > frequently used operations in the engine - function calls - while > providing absolutely no benefit for 100% of existing code and 99.99% of > future code. >
I'd assume that this isn't yet the final patch and it will be improved to make sure that there is no significant performance regression for function calls not making use of autoloading. This should just be a matter of inlining the part of the function with the direct hash lookup and avoiding a duplicate lcname call. (Maybe in the engine just keep the old if (zend_hash_find(...)) and add an else { autoload(); }.) Putting autoloading of different entities into one function makes very
> little sense to me - why would the same code load both classes and > functions?
I don't think it makes much sense to use the same function to autoload classes and functions, but I think it makes sense to autoload both functions and constants with the same mechanism, because presumably both would follow the same naming-convention (e.g. the namespace-to-file mapping mentioned above). So I think this is a useful feature and I definitely don't see a reason why we need to explicitly prevent it. Anyway, I'm +1 on this :) PHP has been neglecting it's functional sides. The "use function" RFC and this one work on improving this a bit. Nikita

Anthony Ferrara

13 years ago
Stas, Moreover, since this replaces a simple hash lookup with additional two
> function calls (and also other operations included in those) everywhere > in the engine, it will also have performance impact of one of the most > frequently used operations in the engine - function calls - while > providing absolutely no benefit for 100% of existing code and 99.99% of > future code. >
This was already directly covered in the RFC already: https://wiki.php.net/rfc/function_autoloading#c_api_backwards_compatibility Basically, two new macros are introduced which expand directly to hash lookups. #define ZEND_LOOKUP_FUNCTION_BY_NAME(name, name_length, fbc) (zend_hash_find(EG(function_table), (name), (name_length) + 1, (void**) (fbc)) == SUCCESS || zend_lookup_function((name), (name_length), (fbc)) == SUCCESS) So nothing changes from present (at all) unless a function is not defined. Today, that's an error case. So the only performance change occurs if zend_hash_find (which is already there) returns FAILURE. THEN the logic which includes autoloading would run. So no, there should be no performance impact at all to existing code thanks to operator short circuiting. Anthony

Stas Malyshev

13 years ago
Hi!
> So nothing changes from present (at all) unless a function is not > defined. Today, that's an error case. So the only performance change > occurs if zend_hash_find (which is already there) returns FAILURE. THEN > the logic which includes autoloading would run.
I see a number of places where hash lookup is replaced with zend_lookup_function, not with the macro. Moreover, zend_lookup_function for some reason copies and lowercases the argument, even though for hash lookup it should already be lowercased.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Anthony Ferrara

13 years ago
Stas, I see a number of places where hash lookup is replaced with
> zend_lookup_function, not with the macro. Moreover, zend_lookup_function > for some reason copies and lowercases the argument, even though for hash > lookup it should already be lowercased.
There was quite literally one place I forgot to switch to the macro expansion (in zend_API.c, zend_is_callable_check_func). I'm sorry. That has been rectified. As far as it being already lowercased, based on the original implementation before refactor, I couldn't hold that as true. So I had implemented it very similar to lookup_class. However, after the refactor (the current state of the patch), it is redundant. I have pushed a commit to refactor that away. Thanks Anthony

Anthony Ferrara

13 years ago
Stas, On Fri, Aug 30, 2013 at 12:57 AM, Stas Malyshev <smalyshev@sugarcrm.com>wrote:
> Hi! > > > I have created a new draft RFC implementing function and constant > > autoloading in master: > > > > https://wiki.php.net/rfc/function_autoloading > > > > All feedback is welcome. > > I think it is an unnecessary complication. Classes fit autoloader > paradigm nicely, since the usual pattern is one class per one file > (actually recommended in PSR), so it is easy to establish one-to-one > automatic mapping between classes and files (also recommended in the > PSR). But for functions nobody does this. This means that to implement > function autoloader one will need to have a complicated and fragile > logic (since there's no way to ensure this logic would be in sync with > actual content of files containing multiple functions).
I don't think that's a fair argument. It's a bit "We don't support function autoloading, so function autoloading doesn't make sense". As far as complicated and fragile logic, as Nikita pointed out, you could put all of your functions inside of a "functions,php" in a particular namespace. Then, with use function, you can capture the missing function call, and cut off the function name, require_once /path/to/namespace/functions.php, and be good. Or, alternatively, you can keep a mapping of function->filename. There's no need or requirement for one-class, one-function or one-constant. Furthermore, I think that's up to the community to decide how to do. They mostly settled on a 1-class-to-1-file rule (which was not the case prior to __autoload/spl_autoload). I am fully confident that they will find a way that makes sense, if given the ability.
> Putting autoloading of different entities into one function makes very > little sense to me - why would the same code load both classes and > functions? How would it do that besides ugly switch that just stuffs two > completely different logic pieces into one function for no reason? The > example given in the RFC is certainly not what anybody would actually > want their autoloaders to do, so I fail to see any case for doing it and > for putting loading more than one entity into one function (that given > that autoloading function would be desirable at all, which it still > doesn't seem so for me). >
That's why this is a RFC which is up for discussion. That's why this is a draft instead of a proposal. Would you rather see: bool php\autoload_class_register($callback, $prepend)) bool php\autoload_function_register($callback, $prepend) bool php\autoload_constant_register($callback, $prepend) Would you rather having the single autoload regstier, but enforcing that type must be a single type? Would you rather see interfaces? interface php\Autoloader {} interface php\AutoloaderClass extends php\Autoloader { public function loadClass($name); } interface php\AutoloaderFunction extends php\Autoloader { public function loadFunction($name); } interface php\AutoloaderConstant extends php\Autoloader { public function loadConstant($name); } bool php\autoload_register(php\Autoloader $loader, $prepend); The syntax provided in this RFC is a proposal. It's not set in stone. If you don't like it, let's work towards a better one! Thanks, Anthony

Stas Malyshev

13 years ago
Hi!
> As far as complicated and fragile logic, as Nikita pointed out, you > could put all of your functions inside of a "functions,php" in a
It's the same as making it Functions.php and a class. I don't see why we should overhaul the autoloading in the engine and add so many complexity just to avoid writing the word "class".
> Or, alternatively, you can keep a mapping of function->filename. There's > no need or requirement for one-class, one-function or one-constant.
One-class-per-file is a very frequent usage pattern. One-function-per-file never happens. That's the difference.
> Furthermore, I think that's up to the community to decide how to do. > They mostly settled on a 1-class-to-1-file rule (which was not the case > prior to __autoload/spl_autoload). I am fully confident that they will > find a way that makes sense, if given the ability.
This sounds like a solution in search of a problem. I don't think we should create solutions for problems that do not exist and then tell people "now go find some problem that may fit this neat code that I've added to the engine". We should first identify the need and only then mess with the engine, not the other way around.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Tyler Sommer

13 years ago
On Aug 30, 2013, at 10:25 AM, Stas Malyshev <smalyshev@sugarcrm.com> wrote:
> >> Furthermore, I think that's up to the community to decide how to do. >> They mostly settled on a 1-class-to-1-file rule (which was not the case >> prior to __autoload/spl_autoload). I am fully confident that they will >> find a way that makes sense, if given the ability. > > This sounds like a solution in search of a problem. I don't think we > should create solutions for problems that do not exist and then tell > people "now go find some problem that may fit this neat code that I've > added to the engine". We should first identify the need and only then > mess with the engine, not the other way around. >
The problem exists: us users need a way to better organize our procedural codebases than manually managing a million require statements. You guys have now given us importing of functions, which is a great step forward. But we still need a way to intelligently load them.

Sebastian Bergmann

13 years ago
Am 30.08.2013 03:23, schrieb Anthony Ferrara:
> All feedback is welcome.
Can we please get rid off the __autoload() function first before we consider adding new functionality?
-- Sebastian Bergmann Co-Founder and Principal Consultant http://sebastian-bergmann.de/ http://thePHP.cc/

Julien Pauli

13 years ago
On Fri, Aug 30, 2013 at 9:35 AM, Sebastian Bergmann <sebastian@php.net>wrote:
> Am 30.08.2013 03:23, schrieb Anthony Ferrara: > > All feedback is welcome. > > Can we please get rid off the __autoload() function first before we > consider adding new functionality? >
Huge +1 to start deprecating this feature, then completely remove it. And to continue the discussion, I recall that we, as PHP contributors, disagreed to include a PSR-0 compatible autoloader into Core. So the argument of PSR-0 is not valid for me, as it has nothing to do with PHP internals and actually is "just a recommandation" we didn't want to merge into PHP. Perhaps is it also time to talk about this subject back and finally all agree on a default recommanded implentation of autoloading in PHP (internally supported) ? Julien.Pauli

Sebastian Bergmann

13 years ago
Am 30.08.2013 10:42, schrieb Julien Pauli:
> Perhaps is it also time to talk about this subject back and finally all > agree on a default recommanded implentation of autoloading in PHP > (internally supported) ?
The only autoloader implementation that makes sense to me is to use a tool such as https://github.com/theseer/Autoload to generate the code. That being said, I do not thinkthat the PHP project should recommend a specific tool but rather the concept.
-- Sebastian Bergmann Co-Founder and Principal Consultant http://sebastian-bergmann.de/ http://thePHP.cc/

Stas Malyshev

13 years ago
Hi!
> And to continue the discussion, I recall that we, as PHP contributors, > disagreed to include a PSR-0 compatible autoloader into Core.
This has nothing to do with PSR-0 in core. This has everything to do with the fact that class-per-file is an accepted pattern in PHP and many other languages, and considered by many to be the best practice. However, nobody uses function-per-file.
> Perhaps is it also time to talk about this subject back and finally all > agree on a default recommanded implentation of autoloading in PHP > (internally supported) ?
Again, it does not matter *how* classes are matched to files and where the slashes are put in. What matters is that classes and files are roughly in one-to-one correspondence (there are exceptions, but there are just that - exceptions - and usually for classes that aren't part of public API). So I'd like not to sidetrack the discussion into discussing which way of putting slashes in is the best and whether PHP core should have backslash-to-forward-slash function. It is not what it is about.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Julien Pauli

13 years ago
On Fri, Aug 30, 2013 at 3:23 AM, Anthony Ferrara <ircmaxell@gmail.com>wrote:
> All, > > I have created a new draft RFC implementing function and constant > autoloading in master: > > https://wiki.php.net/rfc/function_autoloading > > All feedback is welcome. >
Just to say : one benefit of this work would be to finally have autoload functionnality (which is a Core feature IMO) included in Zend/ and no more in an extension. Julien.Pauli

Johannes Schlueter

13 years ago
On Fri, 2013-08-30 at 10:49 +0200, Julien Pauli wrote:
> Just to say : one benefit of this work would be to finally have autoload > functionnality (which is a Core feature IMO) included in Zend/ and no more > in an extension.
What is the benefit, except having more stuff in the engine? SPL is part of the core. Let's not pack the engine with stuff not needed there. johannes

Pierre Joye

13 years ago
On Fri, Aug 30, 2013 at 11:46 AM, Johannes Schlüter <johannes@schlueters.de> wrote:
> On Fri, 2013-08-30 at 10:49 +0200, Julien Pauli wrote: >> Just to say : one benefit of this work would be to finally have autoload >> functionnality (which is a Core feature IMO) included in Zend/ and no more >> in an extension. > > What is the benefit, except having more stuff in the engine? SPL is part > of the core. Let's not pack the engine with stuff not needed there.
Can we stop this madness of considering SPL as non standard or as a 'let put everything we don't know in there' extension? It was created to provided some standard advanced functions or structures. SPL was then used to work around some of the limitation of the engine, or add features not desired by some of the core devs, because no compromise was found. This must end, either it is needed and should be in the engine, or it is not and can go in pecl. SPL is standard, and always enabled. It should not continue to become a 2nd layer to the engine but to provide advanced features like what it initially did.
-- Pierre @pierrejoye | http://www.libgd.org

Bryan C. Geraghty

13 years ago
The problem I see with implementing this kind of functionality in Core is that it relies heavily on convention; PSR-0 is specifically a configuration of the core autoloader which allows any configuration, as it should. And while most of the community has adopted PSR-0 (as have I), I do not think Core is the place for it. Bryan -----Original Message----- From: julienpauli@gmail.com [mailto:julienpauli@gmail.com] On Behalf Of Julien Pauli Sent: Friday, August 30, 2013 3:50 AM To: Anthony Ferrara Cc: internals@lists.php.net Subject: Re: [PHP-DEV] [DRAFT] [RFC] Function autoloading Just to say : one benefit of this work would be to finally have autoload functionnality (which is a Core feature IMO) included in Zend/ and no more in an extension. Julien.Pauli

Bryan C. Geraghty

13 years ago
Having said that, I think the overall concept of function autoloading is a useful feature and haven't seen a good argument for why it shouldn't be supported. Bryan -----Original Message----- From: Bryan C. Geraghty [mailto:bryan@ravensight.org] Sent: Friday, August 30, 2013 8:13 AM To: 'Julien Pauli' Cc: 'internals@lists.php.net' Subject: RE: [PHP-DEV] [DRAFT] [RFC] Function autoloading The problem I see with implementing this kind of functionality in Core is that it relies heavily on convention; PSR-0 is specifically a configuration of the core autoloader which allows any configuration, as it should. And while most of the community has adopted PSR-0 (as have I), I do not think Core is the place for it. Bryan -----Original Message----- From: julienpauli@gmail.com [mailto:julienpauli@gmail.com] On Behalf Of Julien Pauli Sent: Friday, August 30, 2013 3:50 AM To: Anthony Ferrara Cc: internals@lists.php.net Subject: Re: [PHP-DEV] [DRAFT] [RFC] Function autoloading Just to say : one benefit of this work would be to finally have autoload functionnality (which is a Core feature IMO) included in Zend/ and no more in an extension. Julien.Pauli

Stas Malyshev

13 years ago
Hi!
> Just to say : one benefit of this work would be to finally have autoload > functionnality (which is a Core feature IMO) included in Zend/ and no more > in an extension.
PHP core already has autoload functionality. And I don't see how with function autoloading (which has no natural mapping at all) it is even possible to have any mapping worth including into core as a standard. Most functional code I've seen isn't even namespaced, and if you already convert old code to namespaces and need autoloading, you could as well wrap it in a class - I don't see why it's not possible.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Anthony Ferrara

13 years ago
All, I have updated the RFC to include 2 new benchmarks. For normal class loading, this proposal shows at worst no change to loading time. At best, it may actually improve it because at least one zend_function_call is avoided (to spl_autoload_call). For constants and function calls, the benchmark shows that the difference is well within the margin of error for the test (considering variances of 5% to 10% were common in my running of the tests). So hopefully this will dispel any worry about performance regressions in currently defined cases. The times where performance will take a hit, is with undefined functions and constants. Today, an undefined function will fatal error, so this performance hit would be 0, as it would enable something that's not possible today. The only regression can be where autoloaders are defined, and people are relying on the legacy undefined constant behavior (which triggers an E_NOTICE). Anthony On Thu, Aug 29, 2013 at 9:23 PM, Anthony Ferrara <ircmaxell@gmail.com>wrote:

Nicolas Grekas

13 years ago
Hi The only regression can be where autoloaders are defined, and people are
> relying on the legacy undefined constant behavior (which triggers an > E_NOTICE). >
that makes me think about this code : <?php namespace foo; bar(); ?> What autoload should be triggered? "foo\bar" or "bar"? Both are valid isn't it? Should autoloading functions and constants be restricted to namespaced ones only? Then the BC issue you spot would disappear.

Leigh

13 years ago
On Aug 30, 2013 1:31 PM, "Anthony Ferrara" <ircmaxell@gmail.com> wrote:
> For constants and function calls, the benchmark shows that the difference > is well within the margin of error for the test (considering variances of > 5% to 10% were common in my running of the tests). > > So hopefully this will dispel any worry about performance regressions in > currently defined cases. > > The times where performance will take a hit, is with undefined functions > and constants. Today, an undefined function will fatal error, so this > performance hit would be 0, as it would enable something that's not > possible today.
I would assume there is actually potential for performance gain for functions being autoloaded in larger codebases when the *_once calls are removed that would normally load the common functions files.

Laruence

13 years ago
On Sat, Aug 31, 2013 at 12:13 AM, Leigh <leight@gmail.com> wrote:
> On Aug 30, 2013 1:31 PM, "Anthony Ferrara" <ircmaxell@gmail.com> wrote: >> For constants and function calls, the benchmark shows that the difference >> is well within the margin of error for the test (considering variances of >> 5% to 10% were common in my running of the tests). >> >> So hopefully this will dispel any worry about performance regressions in >> currently defined cases. >> >> The times where performance will take a hit, is with undefined functions >> and constants. Today, an undefined function will fatal error, so this >> performance hit would be 0, as it would enable something that's not >> possible today. > > I would assume there is actually potential for performance gain for > functions being autoloaded in larger codebases when the *_once calls are > removed that would normally load the common functions files.
I just reply to this point: No. thinking we already have opcache there. so, *compiling* Functions is cheap. but if with function autoloading, *function autoloading* will execute every run. thanks
-- Laruence Xinchen Hui http://www.laruence.com/

Jordan DeLong

13 years ago
On Fri, Aug 30, 2013 at 05:13:05PM +0100, Leigh wrote:
> On Aug 30, 2013 1:31 PM, "Anthony Ferrara" <ircmaxell@gmail.com> wrote: > > For constants and function calls, the benchmark shows that the difference > > is well within the margin of error for the test (considering variances of > > 5% to 10% were common in my running of the tests). > > > > So hopefully this will dispel any worry about performance regressions in > > currently defined cases. > > > > The times where performance will take a hit, is with undefined functions > > and constants. Today, an undefined function will fatal error, so this > > performance hit would be 0, as it would enable something that's not > > possible today. > > I would assume there is actually potential for performance gain for > functions being autoloaded in larger codebases when the *_once calls are > removed that would normally load the common functions files.
Maybe of interest: We got a performance win from exactly this at Facebook. We have some extensions in HHVM to autoload that allowed us to remove almost all our *_once calls. We have user code register an "autoload map" with the runtime at the beginning of most requests (an array mapping class/function names to which files to load), so we don't normally execute any user code to figure out which file needs loading. (There's various other optimizations to avoid autoload on top of that too.) I don't know enough about PHP internals to know if that approach would work as well here, though. -Jordan

Stas Malyshev

13 years ago
Hi!
> We got a performance win from exactly this at Facebook. We have some > extensions in HHVM to autoload that allowed us to remove almost all > our *_once calls.
But autoloading does not remove require - you still have to load the files. Only thing that can be removed is a non-loading require. Is it that frequent that it had significant performance impact (given that with opcode caching non-loading require is pretty much a couple of hash lookups)?
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Sebastian Krebs

13 years ago
2013/8/31 Stas Malyshev <smalyshev@sugarcrm.com>
> Hi! > > > We got a performance win from exactly this at Facebook. We have some > > extensions in HHVM to autoload that allowed us to remove almost all > > our *_once calls. > > But autoloading does not remove require - you still have to load the > files.
But it removes many many 'require_once's.
> Only thing that can be removed is a non-loading require. Is it > that frequent that it had significant performance impact (given that > with opcode caching non-loading require is pretty much a couple of hash > lookups)? >
Those, who doesn't wrap anything in classes, can see this very frequently.
> > -- > Stanislav Malyshev, Software Architect > SugarCRM: http://www.sugarcrm.com/ > (408)454-6900 ext. 227 > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- github.com/KingCrunch

Jordan DeLong

13 years ago
On Fri, Aug 30, 2013 at 03:21:47PM -0700, Stas Malyshev wrote:
> Hi! > > > We got a performance win from exactly this at Facebook. We have some > > extensions in HHVM to autoload that allowed us to remove almost all > > our *_once calls. > > But autoloading does not remove require - you still have to load the > files. Only thing that can be removed is a non-loading require. Is it > that frequent that it had significant performance impact (given that > with opcode caching non-loading require is pretty much a couple of hash > lookups)?
For us it saved unnecessary loading requires due to transitive module dependencies, as well. I'd suspect it is unlikely to matter in nearly the same way on smaller codebases, though. -Jordan