2011-09-18 91 views
3

我一直在使用PHP很长一段时间,但现在开始尝试使用新的语言功能,如命名空间。我有一个关于自动加载的问题,我无法在我的网页搜索中找到适当的答案。自动加载和命名空间

假设我有不同的命名空间中的类:

namespace foo\bar\baz; 

class Quux 
{ 
} 

namespace fred\barney\wilma; 

class Betty 
{ 
} 

然后假设我有这样的假设,有一个1自动加载磁带机:

function autoload ($className) 
{ 
    $className = str_replace ('\\', DIRECTORY_SEPERATOR, $className); 
    include ($className . 'php'); 
} 

spl_autoload_register ('autoload'); 

是否充分:命名空间和目录结构之间的一对一映射合格的命名空间在所有情况下都会传递给自动加载器,还是自动加载器需要考虑当前使用的名称空间?

例如,如果我做到以下几点:

$a = new \foo\bar\baz\Quux; 
$b = new \fred\barney\wilma\Betty; 

自动加载磁带机应该可以正常工作。

但是,如果我做了以下事情呢?

use \foo\bar\baz as FBB; 
$a = new Quux; 
$b = new \fred\barney\wilma\Betty; 

当试图实例化一个新QUUX,会自动加载磁带机仍然得到\foo\bar\baz\Quux类名的说法?或者它应该得到FBB\Quux,甚至只是Quux

如果是后者,是否可以通过使用__NAMESPACE__或其他类似的机制来确定类应该位于我的自动装载器中的命名空间?

+0

那么你试过的结果是什么? – xdazz

回答

4

自动加载器将获得foo\bar\baz\Quux作为类名称参数。

命名空间名称定义
限定名称
这是一个标识符 没有命名空间分隔,如富

合格名字
这是一个命名空间分隔符的标识符,例如 为Foo \ Bar

标准名称
这是一个标识符,其名称空间分隔符 开头w使用命名空间分隔符,例如\ Foo \ Bar。 命名空间\ Foo也是一个完全限定名称。

而且规则是:

所有不合格和合格的名称(不完全合格的名称)是 根据当前的导入规则在编译时转换。例如,对于 示例,如果将名称空间A \ B \ C导入为C,则调用C \ D \ e()为 ,并将其转换为A \ B \ C \ D \ e()。

+1

对不起,我不得不不接受这个答案。当我尝试实际实现一个像这样工作的自动加载器时,我发现'new/foo/bar/baz()'可以正常工作,但是如果我使用了/ foo/bar, new baz()'我只会让baz被传递给我的自动加载器。 – GordonM

+0

@GordonM你应该做'使用foo \ bar \ baz;新巴兹();'。 – xdazz

+1

是的,我只是想通了。对不起,我只是完全误解了use关键字的工作方式。 – GordonM

0

你会得到一个完全合格的命名空间名称(没有前导反斜杠)。

这也适用于所有其他动态语言结构和功能在PHP中:

如果你写$obj = new $class$class必须是完全合格的,并且不使用任何定义的别名。
如果您编写class_exists($class)$class也必须完全合格。
同样适用于自动加载:它传递完全限定名称。

(唯一的例外,我知道的是define功能,它可以同时使用完全合格的名字,而且还使用不合格的名称,在这种情况下,它会在当前名字空间中定义常量定义。)