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.

Relative name

This is an identifier starting with namespace, such as
namespace\Foo\Bar.

Names are resolved following these resolution rules:

Fully qualified names always resolve to the name without leading namespace separator.
For instance \A\B resolves to A\B.

Relative names always resolve to the name with namespace replaced by
the current namespace. If the name occurs in the global namespace, the
namespace\ prefix is stripped. For example namespace\A
inside namespace X\Y resolves to X\Y\A. The same name
inside the global namespace resolves to A.

For qualified names the first segment of the name is translated according to the current
class/namespace import table. For example, if the namespace A\B\C is
imported as C, the name C\D\E is translated to
A\B\C\D\E.

For qualified names, if no import rule applies, the current namespace is prepended to the
name. For example, the name C\D\E inside namespace A\B,
resolves to A\B\C\D\E.

For unqualified names, the name is translated according to the current import table for the
respective symbol type. This means that class-like names are translated according to the
class/namespace import table, function names according to the function import table and
constants according to the constant import table. For example, after
use A\B\C; a usage such as new C() resolves to the name
A\B\C(). Similarly, after use function A\B\fn; a usage
such as fn() resolves to the name A\B\fn.

For unqualified names, if no import rule applies and the name refers to a class-like symbol,
the current namespace is prepended. For example new C() inside namespace
A\B resolves to name A\B\C.

For unqualified names, if no import rule applies and the name refers to a function or constant
and the code is outside the global namespace, the name is resolved at runtime.
Assuming the code is in namespace A\B, here is how a call to function
foo() is resolved:

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.