主题
  • 默认模式
  • 浅蓝色模式
  • 淡绿色模式
  • 深夜模式

PHP 命名空间

在 PHP 5.3 之前,所有常量、类和函数名都放在全局空间下,这时候就导致了混乱的命名。

命名空间机制通过划分独立的代码作用域,有效地避免了命名冲突的问题,还提高了代码的可读性和组织性。

命名空间必须是文件中的第一个语句(declare除外)。


定义命名空间

命名空间通过namespace关键字声明。基本语法结构如下:

<?php
namespace MyProject; // 定义命名空间

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }

如果命名空间使用分层结果,使用反斜杠\分隔,属于分层命名空间

<?php
namespace MyProject\Sub\Level;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }

如果不定义命名空间,代码属于全局代码(无命名空间)

<?php
// 这段代码在全局空间
class MyClass { /* ... */ }

使用命名空间

✅ 在 PHP 中,命名空间下的类名可以通过以下三种方式引用:

  • 完全限定名称(Fully Qualified Name)
    在命名空间解析机制中,完全限定名称是以\开头的完整命名空间路径,例如:\App\Controllers\UserController,这种形式会直接定位到目标类,不受当前命名空间影响,所以不需要定义命名空间。
  • 限定名称(Qualified Name)
    在命名空间解析机制中,限定名称是基于当前命名空间的相对路径,例如:在 App命名空间下,使用Controllers\UserController会被解析为完整的App\Controllers\UserController
  • 非限定名称(Unqualified Name)
    在命名空间解析机制中,非限定名称是指仅使用类名本身(如UserController),PHP 会先在当前命名空间内查找,若未找到则回退到全局命名空间(\)中查找。例如,直接使用Exception会优先匹配当前命名空间的Exception类,若不存在则使用 PHP 内置的\Exception

✅ 下面通过具体示例来演示这三种命名空间下的类名引用方式,帮助您更直观地理解其工作机制:

1. 完全限定名称实例:

<?php
namespace App\Models;

class User {
    public function pay() {
        // 使用完全限定名称实例化不同命名空间的类
        $payment = new \App\Services\PaymentService();
        return $payment->process();
    }
}

说明:无论当前在哪个命名空间下,都会直接定位到App\Services\PaymentService类。

2. 限定名称实例:

<?php
namespace App\Controllers;

class UserController {
    public function create()
    {
        // 相对当前命名空间 App\Controllers
        $model = new \App\Models\User();  // 完全限定
        $service = new Services\UserService();  // 解析为 App\Services\UserService
        $validator = new \App\Validators\UserValidator();  // 完全限定

        return $model;
    }
}

说明:以当前命名空间App\Controllers为基准,相对引用Models\User

3. 非限定名称实例:

<?php

namespace App\Services;

class UserService {
    public function handle()
    {
        $user = new User();  // 尝试查找 App\Services\User

        try {
            // 查找 App\Services\Exception,不存在则使用 \Exception
            throw new Exception('Error');
        } catch (Exception $e) {  // 同样适用
            $logger = new \App\Utils\Logger();  // 完全限定
            $logger->log($e);
        }
    }
}

class User {}  // 这个类会被上面的 new User() 找到

说明:说明:优先在当前命名空间查找,找不到时回退到全局空间。

✅ 完整项目结构说明:

/var/www/
├── App/
│   ├── Controllers/
│   │   └── UserController.php
│   ├── Models/
│   │   └── User.php
│   ├── Services/
│   │   └── UserService.php
│   │   └── PaymentService.php
│   ├── Validators/
│   │   └── UserValidator.php
│   └── Utils/
│       └── Logger.php
└── index.php

命名空间的导入与别名

1. use 关键字

use关键字用于导入其他命名空间:

namespace MyProject;

use OtherProject\SomeClass;

$obj = new SomeClass();

2. 使用别名

可以为导入的类或命名空间创建别名:

namespace MyProject;

use OtherProject\SomeClass as MyAlias;

$obj = new MyAlias();

3. 导入多个类

可以一次导入多个类:

namespace MyProject;

use OtherProject\ClassA, OtherProject\ClassB as B;

$objA = new ClassA();
$objB = new B();

4. 导入整个命名空间

可以导入整个命名空间:

namespace MyProject;

use OtherProject\Sub as OtherSub;

$obj = new OtherSub\SomeClass();


评论区 0
发表评论