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

Reply via email to