【问题标题】:Troubleshooting "The use statement with non-compound name ... has no effect"疑难解答“具有非复合名称的 use 语句......没有效果”
【发布时间】:2012-03-08 04:33:40
【问题描述】:

当我将use Blog; 放在顶部时出现此错误。

警告:使用非复合名称“博客”的 use 语句无效 在...

Blog 是我的命名空间,其中有 3 个类:文章、列表和类别以及一些函数。

如果我将 statememnt 更改为 use Blog\Article;,那么它可以工作...

我不能只指定我想使用的命名空间吗?我需要提供课程吗?

如果我在该命名空间中有函数怎么办?当我在命名空间之外调用它们时,我不得不在每个人的名字前面加上 \Blog\...

【问题讨论】:

  • 不,我没有使用任何框架
  • 当我声明我的文件namespace 之后 use Blah;时发生在我身上。
  • 这也可能意味着“博客”已经被包含在内,并且您正在尝试第二次使用它。如果您使用的框架已经包含在更高的链上,这很常见。
  • @DerekIllchuk 如果这可能是我可以投票的答案。帮我省了很多麻烦。

标签: php namespaces


【解决方案1】:

PHP 的 use 与 C++ 的 using namespace 不同;它允许您定义一个别名,而不是“导入”一个命名空间,因此以后完全省略命名空间限定符。

所以,你可以这样做:

use Blog\Article as BA;

...缩短它,但你不能完全摆脱它。


因此,use Blog 没用,但我相信你可以写:

use \ReallyLongNSName as RLNN;

请注意,您必须在此处使用前导 \ 来强制解析器知道 ReallyLongNSName 是完全限定的。 Blog\Article 不是这样,它显然已经是一个命名空间链:

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

【讨论】:

  • 啊,太糟糕了。所以use 这个东西实际上没用,还不如是它的首字母缩略词:)
  • @thelolcat:它有它的用途......只是不是你想要的。 :)它确实看起来可能是一个烦人的限制。
  • 此答案仅适用于非命名空间文件。 1) 在命名空间文件中,不需要在use 语句中使用前导\,因为它的参数总是被视为绝对的(即,从全局命名空间开始)。 2) use Blog; 不一定是无用的:例如,从命名空间为Blog\Util\CLI 的文件中,它可以让你写Blog\Entry::method() 而不是\Blog\Entry::method()。并不是说这真的有必要,但它确实有效果。有关此用法的示例,请参阅 Nette 框架。
【解决方案2】:

由于此问题在 Google 上显示为该错误的第一个结果,因此我将说明我是如何修复它的。

基本上,如果你有一个框架,比如 Yii2,你将习惯于声明类,例如:

use Yii;
use yii\db\WhatEver;

class AwesomeNewClass extends WhatEver
{
}

您将在Use Yii 上收到此错误,因为此类没有命名空间。

由于这个类没有命名空间,它会自动继承全局符号表,因此不需要这样定义,只需将其删除即可。

【讨论】:

  • 是的!这很有意义! :)
  • 对我来说,问题是我试图使用全局命名空间中的符号,例如use \Password 但是当您尝试在没有别名的情况下这样做时,php 不喜欢它,所以即使 use \Password as Password 也可以正常工作。
  • 当版主在寻找有关名称空间使用的更一般性答案时,建议使用 OOD 被否决。
  • @JoshH 你在干什么?我什至没有得到你的最后答复。你已经从说这不是一些版主想要的,到给一些人关于 OOP 拖钓的链接
  • @JoshH(顺便说一句,当人们将这样的固执己见的博客作为回答问题的权威材料时,我讨厌它)
【解决方案3】:

use statement in PHP 实际上只是为了方便将长名称空间别名为可能更易于阅读的名称。除了提供便利之外,它实际上不包含任何影响您的开发的文件或执行任何其他操作。因为,Blog 没有别名为任何你没有获得任何便利的东西。我可以想象你可以做类似的事情

use \Blog as B;

这甚至可能奏效。 (可以说你实际上通过模糊在这里失去了便利,但这不是问题所在)因为你实际上是在将 Blog 命名空间别名为其他东西。使用Blog\Article 有效,因为根据文档:

// this is the same as use My\Full\NSname as NSname
use My\Full\NSname;

所以你的 sn-p 相当于:

use Blog\Article as Article;

【讨论】:

  • 请不要打电话给任何人B,除非您正在积极编写无法维护的代码或非常希望引起其他人的头疼。
【解决方案4】:

如果你不想使用像 'as' 这样的语法

use \Blog as B;

为文件定义一个命名空间

namespace anyname;

use Blog

【讨论】:

    【解决方案5】:

    如果您尝试在类定义之前使用特征,也会弹出错误“使用语句...无效...”。

    use My_trait; // should not be here
    
    class My_class{
    // use My_trait; should be here instead
    }
    

    【讨论】:

      【解决方案6】:

      Blog 已经可用,因此您可以使用$article = new Blog\Article(); 而无需顶部的use Blog;。这正是错误告诉您的内容 - 添加的行无效。 use SingleNonNestedClassThatIsAlreadyPresentInTheCurrentNamespace; 是没有意义的,除非你想用 use SingleNonNestedClassThatIsAlreadyPresentInTheCurrentNamespace as Phew; 给它起别名。

      另一方面,如果你想使用$article = new Article();,那么use代表“有用”(笑话),你必须使用use Blog\Article;,相当于use Blog\Article as Article;

      实际上你会做类似的事情

      use Some\TooLong\Namespace\App\User;
      use Some\TooLong\Namespace\App\Ecommerce;
      use Some\TooLong\Namespace\App\Auth;
      

      但不一定

      use Some\TooLong\Namespace\App\Ecommerce\Cart;
      use Some\TooLong\Namespace\App\Ecommerce\Checkout;
      

      也是。我很肯定有比这更好的例子;)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-15
        • 1970-01-01
        相关资源
        最近更新 更多