“具有非复合名称的 use 语句... 无效”疑难解答

当我把 use Blog;放在顶部时得到这个错误。

警告: 非复合名称“ Blog”的 use 语句没有效果 在..。

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

如果我把我的声明改成 use Blog\Article;那就行了。

我不能只指定我想要使用的名称空间吗? 我需要提供类吗?

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

210875 次浏览

PHP's use isn't the same as C++'s using namespace; it allows you to define an 化名, not to "import" a namespace and thus henceforth omit the namespace qualifier altogether.

所以,你可以这样做:

use Blog\Article as BA;

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


因此,use Blog是无用的,但我相信你可以写:

use \ReallyLongNSName as RLNN;

注意,这里必须使用前导 \来强制解析器知道 ReallyLongNSName是完全限定的。对于 Blog\Article来说,情况并非如此,它显然已经是一个名称空间链:

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

PHP 中的 use语句实际上只是为了方便将一个长名称空间别名为一些更容易阅读的内容。除了提供方便之外,它实际上不包含任何影响开发的文件或做任何其他事情。因为,Blog不是别名,因为你没有获得任何方便。我可以想象你可以

use \Blog as B;

甚至可能会成功。(可以说,模糊处理实际上会给你带来不便,但这不是问题的关键)因为您实际上将 Blog名称空间别名为其他名称空间。使用 Blog\Article有效,因为根据文件:

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

所以你的代码片段相当于:

use Blog\Article as Article;

由于这个问题出现在谷歌上的第一个结果为这个错误,我将说明我如何修复它。

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

use Yii;
use yii\db\WhatEver;


class AwesomeNewClass extends WhatEver
{
}

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

Since this class has no namespace it automatically inherits the global symbol table and so does not need things like this defining, just remove it.

如果您尝试在类定义之前使用 trait,那么错误“ The use statement... has no effect...”也会弹出。

use My_trait; // should not be here


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

if you don't want to use 'as' syntax like

use \Blog as B;

为文件定义命名空间

namespace anyname;


use Blog

也许是这样

namespace Path\To\Your\Namespace\Blog;


use Blog; // Redundant


class Post {
public $linkedArticle;


public function __construct($article = null)
{
$this->linkedArticle = $article ?? new Blog\Article();
}
}

Blog is already available, because that's the namespace you're in, so you can use new Blog\Article(); without use Blog; at the top. That's exactly what the error tells you - the added line has no effect.

毫无意义:

use SingleNonNestedClassThatIsAlreadyPresentInTheCurrentNamespace;

Useful:

use SingleNonNestedClassThatIsAlreadyPresentInTheCurrentNamespace as Phew;

另一方面,如果您希望使用 new Article(),那么您可以这样做。

namespace Path\To\Your\Namespace\Blog;


use Blog\Article; // Equivalent to "use Blog\Article as Article;"


class Post {
public $linkedArticle;


public function __construct($article = null)
{
$this->linkedArticle = $article ?? new Article();
}
}

在实践中,你会做类似于

// Fairly separated domains
use Some\TooLong\Namespace\App\User;
use Some\TooLong\Namespace\App\Ecommerce;
use Some\TooLong\Namespace\App\Auth;

但不一定

// Two tools in same domain
use Some\TooLong\Namespace\App\Ecommerce\Cart;
use Some\TooLong\Namespace\App\Ecommerce\Checkout;

我肯定还有比这更好的例子;)