疑难解答“具有非复合名称的 use 语句......没有效果”
Posted
技术标签:
【中文标题】疑难解答“具有非复合名称的 use 语句......没有效果”【英文标题】:Troubleshooting "The use statement with non-compound name ... has no effect" 【发布时间】:2012-03-08 04:33:40 【问题描述】:当我将use Blog;
放在顶部时出现此错误。
警告:使用非复合名称“博客”的 use 语句无效 在...
Blog
是我的命名空间,其中有 3 个类:文章、列表和类别以及一些函数。
如果我将 statememnt 更改为 use Blog\Article;
,那么它可以工作...
我不能只指定我想使用的命名空间吗?我需要提供课程吗?
如果我在该命名空间中有函数怎么办?当我在命名空间之外调用它们时,我不得不在每个人的名字前面加上 \Blog\
...
【问题讨论】:
不,我没有使用任何框架 当我声明我的文件namespace
之后 use Blah;
时发生在我身上。
这也可能意味着“博客”已经被包含在内,并且您正在尝试第二次使用它。如果您使用的框架已经包含在更高的链上,这很常见。
@DerekIllchuk 如果这可能是我可以投票的答案。帮我省了很多麻烦。
【参考方案1】:
php 的 use
与 C++ 的 using namespace
不同;它允许您定义一个别名,而不是“导入”一个命名空间,因此以后完全省略命名空间限定符。
所以,你可以这样做:
use Blog\Article as BA;
...缩短它,但你不能完全摆脱它。
因此,use Blog
没用,但我相信你可以写:
use \ReallyLongNSName as RLNN;
请注意,您必须在此处使用前导 \
来强制解析器知道 ReallyLongNSName
是完全限定的。 Blog\Article
不是这样,它显然已经是一个命名空间链:
http://php.net/manual/en/language.namespaces.importing.php请注意,对于命名空间名称(完全限定的命名空间名称包含命名空间分隔符,例如
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;
也是。我很肯定有比这更好的例子;)
【讨论】:
以上是关于疑难解答“具有非复合名称的 use 语句......没有效果”的主要内容,如果未能解决你的问题,请参考以下文章