Classes can be autoloaded through spl_autoload. Functions cannot. This has lead to functions becoming increasingly 2nd class citizens. On the PHP dev list a proposal for PHP 5.4 has been made to allow autoloading of functions. However there are problems in the implementation and it remains to be seen if the RFC will settle down before last call for API changes and we go to 5.4 beta (I sort of doubt it will).
While discussing it yesterday I hit upon an elegant PHP 5.3 legal solution. Whenever you reference a class for the first time the existing autoload system will provide your autoload function with the fully qualified namespace path to the class. So you know implicitly that a namespace is about to get used.
So I thought to myself, if I was going to do namespace functions I would put them all in one file. Same with constants - to be honest likely the same file. So I thought, why can’t the existing class autoload system handle the problem?
I don’t think there’s a reason it can’t. Consider
The class is requested. Say “MyNamespace\MyClass”
The autoloader sees if there’s a “MyNamespace/functions.php” file. If so, it calls require_once() on the file (PHP itself will track whether the file actually needs inclusion).
There are other ways to do this of course. It isn’t foolproof of course, but it’s highly unlikely in a primarily object-oriented system that a class method will call a function from a foreign namespace, and if it does there are still ways to handle this. One is to have the namespace file that defines the function itself call require for any files it depends on.
There was a time that something like this would have attracted more than a few comments. What’s up guys - am I on everyone’s ignore list?
Anyway, this is working well. The core namespace must have it’s definitions loaded via configuration as a member of a list of files we have to load to support the autoloader itself. Previously I had the constants in the configuration - but this was clumsy insofar as these are things that almost should never change.
Because of how Gazelle is structured most all code is already in a class, and no class references functions in another class’ namespace.
So far I haven’t put a function in the definition file, just constants. If I do put a function in there then for testing reasons it must fit two conditions: 1) Have no internal state and 2) Reference no external entities other than (possibly) other functions within the same name space or the PHP core namespace.
Currently, none. But I want to have a mechanism in place just in case. And constants do get defined regularly (easier to change a constant definition than look up a string everywhere). I did have a group of functions that extended the bcmath library, but when the head count reached 5 I decided to put them in a static class because much of the time loading them was pointless overhead as their purpose is narrow.
TBH, I think PHP autoloading is complete pants, together with the stupid one class per file rule.
If you care about performance then you use APC. If you use APC then that has lazy loading (See apc.lazy_functions & apc.lazy_classes). Functions and or class will be only copied out of APC until they are actually needed.