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

两者之间有什么区别:

use Exception;
use \Exception;

或那些:

use Foo\Bar;
use \Foo\Bar;

该手册说:

请注意,对于命名空间名称(完全 合格的名称空间名称包含 命名空间分隔符,例如Foo \ Bar 而不是全球名称 不,例如FooBar),领先 反斜杠是不必要的,不是 允许,因为导入名称必须完整 合格,未处理 相对于当前名称空间。

但是我并不真正理解这一点,因为上述所有变体都可以工作,即,绝对不允许这样做。

查看use \Exception,发现is_global(设置为反斜线时设置)仅在以下情况下用作警告:

namespace {
    use Exception;
}

这告诉我:“具有非复合名称'Exception'的use语句无效”。 (尽管对use \Exception执行相同的操作效果不大,但不会发出警告。)

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

NikiC asked 2020-07-26T21:02:16Z
5个解决方案
34 votes

该手册将反斜杠指定为不必要的,这自然意味着,如果仍使用反斜杠,则其含义是等效的。 但是,正如您所指出的那样,该手册说不允许这样做,这是错误的。

但是,手册还有其他麻烦之处。 他们刊登广告:

// importing a global class
use \ArrayObject;

如果确实没有相对于当前名称空间处理导入名称,则use \Exception;use ArrayObject必须具有相同的含义。 use ArrayObject除了全局变量还可以引用什么? 实际上,引擎将导入全局引擎。

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

我相信对于该标准应该有什么困惑。

要回答您的问题:没有区别。 但是,如果我是引擎开发人员,并且还是不带斜杠标准的信奉者,那么我就不必考虑有人写use \Exception;的情况。我相信可能是这种情况。

erisco answered 2020-07-26T21:02:56Z
13 votes

实际上,目前在导入名称空间中使用前导反斜杠没有区别,PHP手册中的信息也已更改:

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

因此,现在有真正的信息,不建议使用前导反斜杠,但没有任何信息是过去不允许的。

因此,目前:

use Exception;
use \Exception;

这两行的工作原理相同,但您应该使用第一行。

Marcin Nabiałek answered 2020-07-26T21:03:34Z
5 votes

通常,前导反斜杠定义标识符为绝对标识符。 如果缺少,解释器将假定它是一个相对标识符。

这是一个绝对标识符:

$x = new \Name\Space\To\Class();

因为没有斜杠,所以这是一个相对的标识符。 它是相对于当前名称空间的:

namespace Name\Space;
$x = new To\Class;

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

namespace Other\Name\Space;
use Name\Space;
$x = new Space\To\Class;

但是,由于在namespaceuse语句中只允许使用绝对标识符(完全限定的名称),因此可以在此处省略它。 在namespace中,甚至不允许设置领先的反斜杠。

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

KingCrunch answered 2020-07-26T21:04:17Z
-3 votes

不要说我们有

namespace MyNamespace
use Exception;
use \Exception;

然后第一个使用实际上导入类MyNamespace \ Exception,第二个仅导入主类\ Exception

这样你就可以像

namespace MyNamespace;
class Exception extends \Exception{ }

然后我可以

throw new \Exception('Exception from global namespace');
throw new \MyNamespace\Exception('Exception from MyNamespace');
Andy answered 2020-07-26T21:04:50Z
-3 votes

前导反斜杠表示全局名称空间。 如果您在名称空间的范围内,则必须使用该范围才能到达全局名称空间。 例如:

namespace A
{
    class A
    {
        public function __construct()
        {
            echo('namespace: A<br />');
        }
    }
}

namespace B\A
{
    class A
    {
        public function __construct()
        {
            echo('namespace: B\\A<br />');
        }
    }
}

namespace B
{
    class B
    {
        public function __construct()
        {
            new \A\A(); // namespace: A
            new A\A(); // namespace: B\A
        }
    }
    new B();
}

使用反斜杠,您将获得绝对路径,而没有反斜杠,您将获得相对路径。

inf3rno answered 2020-07-26T21:05:14Z
translate from https://stackoverflow.com:/questions/4849279/importing-classes-and-namespaces-in-php-what-difference-does-a-leading-backslas