问题
I've been working with PHP for a long time, but am now starting to experiment with newer language features such as namespaces. I have a question regarding autoloading that I haven't been able to find an adequate answer to in my web searching.
Suppose I have classes in different namespaces:
namespace foo\bar\baz;
class Quux
{
}
namespace fred\barney\wilma;
class Betty
{
}
Then suppose I had an autoloader that assumes that there's a 1:1 mapping between namespaces and directory structures:
function autoload ($className)
{
$className = str_replace ('\\', DIRECTORY_SEPERATOR, $className);
include ($className . 'php');
}
spl_autoload_register ('autoload');
Does the fully qualified namespace get passed to the autoloader under all circumstances, or does the autoloader need to take the namespace currently being used into account?
For example, if I do the following:
$a = new \foo\bar\baz\Quux;
$b = new \fred\barney\wilma\Betty;
the autoloader should work fine.
But what if I do the following?
use \foo\bar\baz as FBB;
$a = new Quux;
$b = new \fred\barney\wilma\Betty;
When attempting to instantiate a new Quux, will the autoloader still get \foo\bar\baz\Quux
as the class name argument? Or should it get FBB\Quux
, or even just Quux
?
If the latter, can I determine the namespace the class is supposed to be in from within my autoloader by using __NAMESPACE__
or some other such mechanism?
回答1:
The autoloader will get foo\bar\baz\Quux
as the class name argument.
Namespace name definitions
Unqualified name
This is an identifier without a namespace separator, such as FooQualified name
This is an identifier with a namespace separator, such as Foo\BarFully qualified name
This is an identifier with a namespace separator that begins with a namespace separator, such as \Foo\Bar. namespace\Foo is also a fully qualified name.
And the the rule is :
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().
回答2:
You will get a fully qualified namespace name (without leading backslash).
This also applies to all other dynamic language constructs and functions in PHP:
If you write $obj = new $class
the $class
must be fully qualified and doesn't use any defined aliases.
If you write class_exists($class)
the $class
must also be fully qualified.
And same applies to autoload: It is passed the fully qualified name.
(The only exception to this rule I know of is the define
function, which can define constants both using fully qualified names, but also using an unqualified name, in which case it will be defined in the current namespace.)
来源:https://stackoverflow.com/questions/7460811/autoload-and-namespaces