Chuck Hagenbuch wrote: > Hi folks- > > I've hit upon something with namespaces and autoloading that I think is > a little out of order. If you take the attached 3 files, put them in the > same directory, and run demo.php, you will see this: > > Fatal error: Uncaught exception 'Exception' in > /Users/chuck/Desktop/test.php:7 > > > If you look at the code, test.php defines a Test:: namespace with a > Tester class that throws an exception, test_exception.php provides an > Exception derivative (Test::Exception) for that namespace, and demo.php > includes test.php, sets up an __autoload function to load the exception > class, and triggers the exception throwing code. > > However autoload is never called and the exception is of type > ::Exception, because the class resolution order seems to look like this: > > - does the class exist (_already defined_) in the current namespace? > - does the class exist in the global (non-prefixed or "::") namespace? > - then try autoload > > What I think should happen is: > > - does the class exist in the current namespace? > - can the class be autoloaded with the current namespace? > - does the class exist in the global scope > - global autoload
Hi Chuck, 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. > 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. For me, the fact that this coding practice is both more efficient than the alternative you suggest and more maintainable makes the choice quite appealing, even if it isn't immediately intuitive. Greg -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php