Re: Re: Order of class resolution with namespaces and autoload

From: Date: Sat, 20 Oct 2007 03:26:04 +0000
Subject: Re: Re: Order of class resolution with namespaces and autoload
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-32879@lists.php.net to get a copy of this message
Quoting Gregory Beaver <greg@chiaraquartet.net>:
Are you suggesting there be namespace-specific autoload? This sounds interesting to me, but also quite complex, not sure the benefits would outweigh the difficulties for implementation. For instance, PEAR2 namespace would be different from PEAR2::Someclass, and one would need to register the same autoload handler for each possible namespace, otherwise the class resolution code would have to grep through each classname to find sub-namespaces, which is most likely an unacceptable performance hog.
Yes, I agree, that sounds awful. :) I was thinking in terms of a duality - say, A::B::C::Exception vs. ::Exception - but when you throw in the possibility that A::B::Exception exists, it sure gets ugly.
Otherwise if you are re-defining a global class, which I imagine will be quite common with Exception at least, you will have to explicitly load your Exception classes or they'll never be used.
There is another alternative: <?php namespace Test; // explicitly tell PHP that we want Test::Exception to be autoloaded (in essence) import Test::Exception; class Tester {
    public function fail() {
        throw new Exception();
    }
} ?> This calls autoload, as expected, and works wonderfully. It is also quite efficient, but at the expensive of intuitiveness. However, it also has the benefit of explicitly declaring external classes at the top of the file, which is a big plus for maintainability when others are looking at your code.
Yes, this works. And I'll readily admit that I don't have a better idea right now. An observation, though: when combined with autoload this can change import from only affecting a single file to affecting all subsequent files. 1.php <? namespace Test; import Test::Exception; throw new Exception(); ?> 2.php <? namespace Test; throw new Exception(); ?> If I define a Test::Exception class and include those files in any order, both will create Test::Exception objects regardless of the import statement. However, if I set up autoload, then things become order-dependent: - If I include 1.php, then 2.php, both files throw Test::Exception - If I include 2.php, then 1.php, I get an Exception and then a Test::Exception I can live with this, but I wonder if taking a bit of magic away from nested namespaces would be better. What's wrong with: - If you are inside a namespace, all classnames that do not include a namespace separator (::) refer to classes of the current namespace. So, if I want a "global" exception, I use ::Exception. If I say Exception, then I mean my namespace's Exception with no fallback. And if I want another namespace's Exception, I import it (import Other::Exception). -chuck

« previous php.internals (#32879) next »