Map-based autoloader across php and phar resources

⌈⌋ ⎇ branch:  Canonic Autoloader


Artifact [4b15e9a39c]

Artifact 4b15e9a39c6df7d6d9dfdb7ba7c2a848bbdaaa3d:

Wiki page [rfc:function_autoloading] by mario 2014-09-04 02:25:52.
D 2014-09-04T02:25:52.513
L rfc:function_autoloading
N text/x-markdown
P 08e479d70a348a0f024bd705dc151b2b04d1ee3e
U mario
W 2707
<h3> Function autoloading </h3>

PHP is a *hybrid* language. It however unevenly implements autoloading for classes only as of now. There are long-standing feature requests for supporting it with all language symbols. A more recent attempt to bring some systematization here was:

See [https://wiki.php.net/rfc/function_autoloading](https://wiki.php.net/rfc/function_autoloading)

The ensuing php-dev discussion wasn't overly constructive. (Fatal errors provide a higher performance than autoloading a function). Backhandedly however to prevent functions becoming first class language constructs, due to their implied and unfavored coding paradigm.

Meanwhile PHP 5.6 introduced [`use function`](https://wiki.php.net/rfc/use_function) imports, which however are aliases only, thus magnifying the dichotomy only further.


### Why is it in shared.phar ?

It's a proof-of-concept mostly. 

Implementing function declaration lookups is a *trivial* by-product of doing things properly anyway.


### How can I use it *now*?

For current PHP versions, you need a workaround like this to shoehorn globally-autoloaded functions into your code:

        /**
         * Userland workaround for function_autoloading.
         * Implements a static class, which random global functions can be
         * invoked with.
         *
         *    x::autoload_me(1,2,3);
         *
         */
         
        class x {
            function __callStatic($name, $args=array()) {
                if (!function_exists($name)) {

                    static $ca;

                    // find suitable autoloaders
                    if (!isset($ca)) {
                        $ca = array();
                        
                        foreach (array_filter("is_object", spl_autoload_functions()) as $spl) {
                            if (is_a($spl, "Canonic_Autoloader")) {
                                $ca[] = $spl;
                            }
                        }
                    }

                    // invoke each autoloader
                    foreach ($ca as $autoload) {
                        $autoload($name, 2);
                    }
                }

                return call_user_func_array($name, $args);
            }
        }

Which obviously is hardly as enchanting as having PHP adhere to its hybrid heritage. And `x::` while an acceptably readable prefix, is not a standard denomination for such a feature.

Though the bemusing part here is, you just need to place `x.php` in your classpath. Then `shared.phar` will autoload both subsequently; first the static `x::` class, then your `autoloaded_func()` prior calling it.
Z 07f0824d1f919b9649b29415d30668de