PHP 命名空间限定 - 为什么我必须完全限定?

标签 php namespaces

我正在从 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/

相关文章:

php - `clone` 比在 PHP 中实例化新对象有什么优势?

php - 将 MySQLi 结果传递给 PHP 中的函数有哪些内存影响?

包含脚本中的 PHP exit(),退出父脚本?

.net - System.Windows.Shell 在哪里?

php - Laravel 基于var 调用静态函数

php - MySQL 连接不上数据库

javascript - 将多维对象转换为查询字符串

C++ "' DOMDocument' : redefinition"Error with Xercesc

python - 在python类中实现归并排序功能,报错

php - Laravel/流明 PSR-4 : If I put classes into subdirectories do I have to use different namespaces then?