【问题标题】:PHP namespaces : \My\Namespace or My\Namespace?PHP 命名空间:\My\Namespace 还是 My\Namespace?
【发布时间】:2011-08-01 20:22:15
【问题描述】:
  • My\Namespace
    • \My\Namespace

所以,我应该使用哪一个,我看到php documentation 主要使用My\Namespace

但据说\My\Namespace更好,因为没有歧义,而My\Namespace可以解析为\RandomNamespace\My\Namespace

在阅读Doctrine 2 中有一个关于此的问题后,我开始对此感到疑惑:“Please replace 'Doctrine\XXX\YYY' with '\Doctrine\XXX\YYY' in code and document

那么,你有更多关于这方面的信息吗? 谢谢

【问题讨论】:

    标签: php namespaces php-5.3


    【解决方案1】:

    这与使用相对和绝对文件/uri 路径没有什么不同,并且会归结为偏好。但是,与绝对路径不同,我同意不那么模棱两可的 \My\Namespace,因为它永远不会中断,而相对名称空间可以。

    命名空间别名,通过use 增加了相对命名空间名称的模糊性。例如,我可以说:use \PDO as YourMom,然后在代码中调用YourMom。是\PDO\YourMOM 还是YourMom 被调用?显然别名获胜并被解析为\PDO,假设没有冲突,但它使代码难以遵循。

    编辑

    证明歧义的代码示例是可能的。如果命名空间不合格,请确保您看到应用了全局 fallback

    正如@netcoder 所提到的,在命名空间的声明 期间不可能有歧义。因此,namespace Mynamespace \My(或交换下面的任何其他命名空间声明)与声明完全限定命名空间是 100% 相同的。

    namespace My
    {
    }
    
    namespace My\Other
    {
        use Bob; // Resolves to \My\Other\Bob
    }
    
    namespace My\Other\NS
    {
        use \My\Other as Other;
        use Other\NS as Duh; // This resolves to \My\Other\NS
    }
    
    namespace My\Other\Bob
    {
        use Other\NS as Duh; // This resolves to \Other\NS becuase the namespace doesn't exist inside \My\Other\Bob
    }
    

    【讨论】:

      【解决方案2】:

      在命名空间声明本身中没有区别。此声明始终定义一个完整的限定名称,因此您可以安全地省略前导命名空间分隔符。 use 语句也是如此。

      namespace My\Namespace;
      // Is exactly the same as 
      namespace \My\Namespace;
      
      use Foo\Bar as Class1;
      // Is exactly the same as 
      use \Foo\Bar as Class2;
      

      在所有其他情况下,前导分隔符确保给定的限定符是绝对的,如果它缺失,它是相对的。请参阅 the manual 了解它们是如何解决的。

      如果您仅使用来自同一命名空间的类和/或通过use(也可能是as)在文件顶部“声明”每个类,您可以安全地使用相对类标识符。

      【讨论】:

        【解决方案3】:

        实际上是有区别的,但并不总是(啊对)。

        use 构造中,您永远不必“提及”前导\。如果类在同一个命名空间中,或者如果您正在使用导入(使用 use ns 导入),则无需进行内联。

        但有时你必须:

        namespace foo;
        
        class bar extends \baz\Bar {
        

        您正在使用未定义/未知/未导入的内联类,因此您必须提及其来源。

        另一个例子是在命名空间中使用未命名空间的类,内联:

        namespace foo;
        
        $dt = new \DateTime;
        

        最佳实践(通常)是导入当前文件需要的所有类。使用声明非常、非常、非常、非常便宜,所以不要犹豫。

        namespace foo;
        
        use baz\Bar AS OtherBar;
        use \DateTime;
        
        class Bar extends OtherBar { // or something like that; in this case (same class name) it's tricky
          function __construct() {
            $dt = new DateTime;
        

        编辑 1
        另外,在将它们作为字符串传递时不要忘记使用完全命名空间的类名,即使您可能在正确的命名空间中:

        namespace foo;
        
        $class = 'foo\bar';
        

        【讨论】:

        • "在 use 结构中,你永远不必'提及'前导 \":为什么? (我只是想把所有的部分放在一起)
        • @MatthieuNapoli 因为use 总是从根开始工作。前导 `` 是隐含的,因此无需键入。没有它就干净多了。哇,这个回复才晚了2.5年……
        • 迟回复还是回复:)
        猜你喜欢
        • 2021-08-04
        • 1970-01-01
        • 2013-02-09
        • 2020-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-19
        • 2012-03-12
        相关资源
        最近更新 更多