在PHP中导入类和命名空间:领先的反斜杠有什么区别?

Nik*_*kiC 45 php import namespaces language-specifications

这两者有什么区别:

use Exception;
use \Exception;
Run Code Online (Sandbox Code Playgroud)

或那些:

use Foo\Bar;
use \Foo\Bar;
Run Code Online (Sandbox Code Playgroud)

手册说:

请注意,对于名称空间名称(包含名称空间分隔符的完全限定名称空间名称,例如Foo\Bar而不是全局名称,例如FooBar),前导反斜杠是不必要的,不允许,因为导入名称必须是完全限定的,并且不会相对于当前名称空间进行处理.

但我并不是真的理解这一点,因为所有上述变种都有效,即它绝对不是"不允许".

看看zend_do_use显示,is_global(设置,当有前导反斜杠时)仅用于以下情况中的警告:

namespace {
    use Exception;
}
Run Code Online (Sandbox Code Playgroud)

这告诉我:"具有非复合名称的'使用声明'异常'无效".(虽然做同样的事情use \Exception会产生很小的影响,但不会发出警告.)

那么:我错过了什么吗?实际上有什么区别吗?

eri*_*sco 34

手册指定反斜杠是不必要的,这自然意味着如果你仍然使用它,意思是等价的.但是,正如您所指出的那样,手册中说它应该是不允许的,这是错误的.

但是,手册还有其他问题.他们做广告:

// importing a global class
use \ArrayObject;
Run Code Online (Sandbox Code Playgroud)

如果确实没有相对于当前名称空间处理导入名称,那么use \ArrayObjectuse ArrayObject必须具有相同的含义.还有什么可以use ArrayObject指除全球的?实际上,引擎将导入全局引擎.

此外,还有这样的错误:http: //bugs.php.net/bug.php?id = 49143

我相信这个标准应该是什么样的混乱.

回答你的问题:没有区别.但是,如果我是发动机开发人员,他也是一个没有领先的斜杠标准的信徒,那么我就不需要考虑有人写的情况use \Exception;.我相信情况可能就是这样.


Mar*_*łek 13

实际上,在导入名称空间时使用前导反斜杠没有区别,PHP手册中的信息也发生了变化:

请注意,对于命名空间名称(包含命名空间分隔符的完全限定的命名空间名称,例如Foo\Bar而不是全局名称,例如FooBar),前导反斜杠是不必要的,不建议使用,因为导入名称必须是完全限定的,并且不会相对于当前名称空间进行处理.

所以现在有一些真实的信息,不推荐使用前导反斜杠,但没有任何信息表明过去它是不允许的.

所以目前:

use Exception;
use \Exception;
Run Code Online (Sandbox Code Playgroud)

这两行的工作方式相同但你应该使用第一行.


Kin*_*nch 5

通常,前导反斜杠定义标识符是绝对的.如果它缺失,则解释器假定它是相对标识符.

这是绝对标识符:

$x = new \Name\Space\To\Class();
Run Code Online (Sandbox Code Playgroud)

这是一个相对标识符,因为没有前导斜杠.它与当前命名空间相关:

namespace Name\Space;
$x = new To\Class;
Run Code Online (Sandbox Code Playgroud)

这也是一个相对标识符.在这种情况下,它针对use语句解析,因为最后一部分(别名)与第一个类相同:

namespace Other\Name\Space;
use Name\Space;
$x = new Space\To\Class;
Run Code Online (Sandbox Code Playgroud)

但是,因为在namespaceuse语句中只允许使用绝对标识符(完全限定名称),所以可以在此处省略它.在namespace,甚至不允许设置前导反斜杠.

有关PHP如何解析不同命名空间声明的更多信息,请参阅命名空间规则手册.