我正在从 C# 转换到 PHP,但在某些地方转换时遇到了问题。特别是命名空间。我遇到的问题是,当从另一个 namespace 调用类时,我必须完全限定每个 namespace 。这正常吗?
<?php
namespace Lib\Things;
class TheThings
{
}
然后在别的类
<?php
namespace App;
use Lib\Things;
class DoStuff
{
public function doStuff()
{
$things = new TheThings();
}
}
那行不通......我最终不得不做
new Lib\Things\TheThings();
或者
<?php
namespace App;
use Lib\Things as T;
class DoStuff
{
public function doStuff()
{
$things = new T\TheThings();
}
}
我的 composer.json 文件中也有这个
"psr-4": {
"App\\": "app/",
"Lib\\": "lib/"
}
这是正常现象还是我做错了什么?
最佳答案
在PHP manual use
关键字被称为导入或别名。
这意味着
use Lib\Things;
和
use Lib\Things as Things;
是一样的。这导致您不必使用完全限定名称从命名空间实例化类,您可以仅使用导入命名空间的别名。因此,在您的情况下,以下方法会起作用:
<?php
namespace App;
use Lib\Things;
// same as:
// use Lib\Things as Things; // explicit alias
class DoStuff
{
public function doStuff()
{
$things = new Things\TheThings();
}
}
(请注意,这与您的第二个示例相同,唯一的区别是别名未在此处明确设置为 T
(默认为 Things
)。
为了能够在没有任何命名空间前缀的情况下使用类名,您必须设置实际类的别名:
<?php
namespace App;
use Lib\Things\TheThings;
// same as:
// use Lib\Things\TheThings as TheThings; // explicit alias
class DoStuff
{
public function doStuff()
{
$things = new TheThings();
}
}
总而言之,如果您开始考虑将 use
运算符设置为命名空间或类(或其他)的别名,您就会掌握它的窍门。
附注 1:
在 PHP 7 之前,如果你想从同一个命名空间导入多个类,你必须这样写:
use some\namespace\ClassA;
use some\namespace\ClassB;
use some\namespace\ClassC as C;
From PHP 7.0 onwards, classes, functions and constants being imported from the same namespace can be grouped together in a single use statement:
use some\namespace\{ClassA, ClassB, ClassC as C};
附注 2:
composer 根据一些 PSR* 规则帮助自动包含/加载实际的 php 文件,它对命名空间在裸 PHP 中的工作方式没有任何作用。
关于PHP 命名空间限定 - 为什么我必须完全限定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39648044/