Hi,

I've been using namespaces for a few months now, and I feel a need for a
specific solution.

I've been thinking a lot about this, and I will explain everything here.

Basically the goal is to be able to overload namespace resolution (ie.
overloading new and static calls).

Basically (case 1), the user would create a function
__resolveclass($classname, $cur_namespace, $used_namespaces) which would
return a string. When new or a static call happens, this function is
called and the final call happens to whatever was returned.
The second argument would contain the current namespace (where the call
happened) and the last one would contain list of "used" namespaces.

It is possible to implement a cache (eg. if the same class is called we
just get the last value we got from __resolveclass()) but in this case a
function like clear_cache_resolver_cache() would be needed.

Another implementation (case 2) of this would be to create virtual
namespaces. In this case a function create_virtual_namespace($namespace,
$callback) would be created, and any new/static call on a class within
the given namespace would call $callback.

The basic idea behind this is to allow this kind of calls :

(from global scope)

use something;
$database = new virtual::SQL();
virtual::SQL::DoSomethingInteresting();

Both calls would call either :

Case 1: __resolveclass('virtual::SQL', '', array('', 'something'));
Case 2: my_callback('virtual', 'SQL'); (first parameter would be the
virtual namespace, the second one would be the class name).

While working with namespaces, I basically had namespaces extending
other namespaces (a collection of classes which extends another
collection of class, and all implement the same interface). However in
some cases one of the class has no need to be extended. In this case
it's just not created.
In order to implement this, I wrote my own "class resolver function"
which will lookup the class' file in current namespace, and in each
"parent namespace" until it finds it, then returns the class name so I
can do a new $class().

Another case where this is necessary is on a totally unrelated project:
we are working on a quite big framework, and the same codebase is being
used for more than 100 websites. The codebase itself is really huge, and
we replace parts as time passes by, and try to write new "modular" code.

Our need was to overload creation of some classes, but only for some
sites which have really specific needs. Since some of those classes are
static, a class factory isn't good enough, and (even if it's our goal)
we can't rewrite the whole code to make it new and better.



Being able to overload the new operator would allow us to make a better
class lookup to fit our needs, and probably other people's needs too,
which can't just be implemented in PHP (the class lookup).

I'm perfectly aware of the risks of obscure code spawning from the hands
of various people if this gets implemented, it was the same when classes
were implemented, when __autoload() was used (I saw people do what I
wrote here using __autoload and eval() to create an empty class
extending the target class on the fly) and there will be with
namespaces, probably with unicode support too.
You can't just create something and expect everyone will use it right,
but at least it's possible to document it and help people avoiding
non-maintainable code.

Anyway right now this is more on the discussion step, I think as PHP
5.3.0 gets released with namespaces, the need for this kind of solution
will arise (I'm probably the only one here who really used namespaces in
a whole PHP project, and saw how useful/harmful they are). If anyone
here have a better solution, I'm ready to implement and test it too.

Anyway a solution is needed before people do things like :

// Eeeeek-autoload, using eval() to create empty classes
function __autoload($class) {
        $aClass = explode('::', $class);
        if ($aClass[0] == 'virtual') {
                $real_class = 'None';
                switch($aClass[1]) {
                        case 'SQL': $real_class = 'MySQL'; break;
                }

                normal_autoload($real_class);
                eval('class '.$class.' extends '.$real_class.' { }');
                return;
        }

        normal_autoload($class);
}

(and it could be even worse, if for example overload is not only for one
namespace but for random class names).

By the way dynamic class lookup is something only runtime languages like
PHP can do, so don't try to compare this to anything found in 
C++/Java/etc (or any other compiled language).


Best regards,
Mark Karpeles


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to