Name resolution rules

For the purposes of these resolution rules, here are some important definitions:

Namespace name definitions

Unqualified name

This is an identifier without a namespace separator, such as Foo

Qualified name

This is an identifier with a namespace separator, such as Foo\Bar

Fully qualified name

This is an identifier with a namespace separator that begins with a
namespace separator, such as \Foo\Bar. The namespace
\Foo is also a fully qualified name.

Names are resolved following these resolution rules:

Calls to fully qualified functions, classes or constants are resolved at compile-time.
For instance new \A\B resolves to class A\B.

All unqualified and qualified names (not fully qualified names) are translated during
compilation according to current
import rules. For example, if the namespace A\B\C is imported as
C, a call to
C\D\e() is translated to A\B\C\D\e().

Inside a namespace, all qualified names not translated according to import
rules have the current namespace prepended. For example, if a call
to C\D\e() is performed within namespace A\B,
it is translated to A\B\C\D\e().

Unqualified class names are translated during compilation according to current
import rules (full name substituted for short imported name). In example, if
the namespace A\B\C is imported as C, new C() is
translated to new A\B\C().

Inside namespace (say A\B), calls to unqualified functions are resolved at run-time.
Here is how a
call to function foo() is resolved:

It looks for a function from the current namespace:
A\B\foo().

It tries to find and call the global function
foo().

Inside namespace (say A\B), calls to unqualified or qualified
class names (not fully qualified class names)
are resolved at run-time. Here is how a call to
new C() or new D\E() is resolved.
For new C():

It looks for a class from the current namespace:
A\B\C.

It attempts to autoload A\B\C.

For new D\E():

It looks for a class by prepending the current namespace:
A\B\D\E.

It attempts to autoload A\B\D\E.

To reference any global class in the global namespace,
its fully qualified name new \C() must be used.

If you keep your directory/file matching namespace/class consistence the object __autoload works fine.But... if you try to give loader.php a namespace you'll obviously get fatal errors. My sample is just 1 level dir, but I've tested with a very complex and deeper structure. Hope anybody finds this useful.

Namespaces may be case-insensitive, but autoloaders most often do.Do yourself a service, keep your cases consistent with file names, and don't overcomplicate autoloaders beyond necessity.Something like this should suffice for most times:

Namespace resolution *only* works at declaration time. The compiler fixates all namespace/class references as absolute paths, like creating absolute symlinks.

You can't expect relative symlinks, which should be evaluated during access -> during PHP runtime.

In other words, namespaces are evaluated like __CLASS__ or self:: at parse-time. What's *not* happening, is the pendant for late static binding like static:: which resolves to the current class at runtime.

It took me playing with it a bit as I had a hard time finding documentation on when a class name matches a namespace, if that's even legal and what behavior to expect. It IS explained in #6 but I thought I'd share this with other souls like me that see it better by example. Assume all 3 files below are in the same directory.

file1.php<?phpnamespace foo;

class foo { static function hello() { echo "hello world!"; }}?>

file2.php<?phpnamespace foo; include('file1.php');

foo::hello(); //you're in the same namespace, or scope.\foo\foo::hello(); //called on a global scope.?>

file3.php<?phpinclude('file1.php');

foo\foo::hello(); //you're outside of the namespace\foo\foo::hello(); //called on a global scope.?>

Depending upon what you're building (example: a module, plugin, or package on a larger application), sometimes declaring a class that matches a namespace makes sense or may even be required. Just be aware that if you try to reference any class that shares the same namespace, omit the namespace unless you do it globally like the examples above.

I hope this is useful, particularly for those that are trying to wrap your head around this 5.3 feature.

If you keep your directory/file matching namespace/class consistence the object __autoload works fine.But... if you try to give loader.php a namespace you'll obviously get fatal errors. My sample is just 1 level dir, but I've tested with a very complex and deeper structure. Hope anybody finds this useful.