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
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.
The other alternative would be to say that if you want to use a global
class inside a namespace you MUST prefix it with ::. I think this is
reasonable since if you have a namespaced file it's already not going
to work with anything before PHP 5.3, and that would remove the two
potential autoload checks.
Thanks,
-chuck
<?php
include './test.php';
function __autoload($class) {
include './test_exception.php';
}
$tester = new Test::Tester();
$tester->fail();
<?php
namespace Test;
class Tester {
public function fail() {
throw new Exception();
}
}
<?php
namespace Test;
class Exception extends ::Exception {
}
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php