首页 / PHP 入门教程 / PHP 命名空间

PHP 入门教程

PHP 命名空间

本教程共 65 篇 · 第 18 篇 · 更新于 2026-07-24 · 约 4 分钟阅读

PHPPHP8命名空间namespace自动加载PSR-4

18. PHP 命名空间

本节目标:掌握命名空间的声明、引用和自动加载。学完你能组织大型项目代码,避免类名冲突。

18.1 为什么需要命名空间

在大型项目中,不同开发者可能创建同名的类。命名空间就像文件夹,把代码划分到不同区域:

<?php
// 没有命名空间时,类名不能重复
class User {}  // 框架 A 的 User
class User {}  // 错误!不能重复定义

// 使用命名空间后,同名类可以共存
namespace FrameworkA;
class User {}

namespace FrameworkB;
class User {}
?>

18.2 声明命名空间

<?php
// 文件开头声明命名空间
namespace App\Controllers;

class HomeController {
    public function index(): void {
        echo "首页";
    }
}
?>
Note

namespace 声明必须是文件中的第一条 PHP 代码(除了 declare())。前面不能有任何输出,包括 HTML 和空格。

18.3 使用 use 引入

<?php
namespace App\Services;

// 引入其他命名空间的类
use App\Models\User;
use App\Models\Order;

class UserService {
    public function getUser(int $id): User {
        return new User();
    }
}
?>

18.4 别名解决冲突

当引入的两个类同名时,使用别名:

<?php
namespace App\Controllers;

use App\Models\User as UserModel;
use Vendor\Package\User as VendorUser;

class ProfileController {
    public function show(): void {
        $user = new UserModel();    // App\Models\User
        $vendorUser = new VendorUser();  // Vendor\Package\User
    }
}
?>
Tip

别名不仅用于解决冲突,也可以简化长类名。use App\Very\Long\Namespace\ClassName as Short;

18.5 完全限定名称

<?php
namespace App;

// 相对名称(当前命名空间下)
$controller = new Controllers\HomeController();

// 完全限定名称(从根开始)
$model = new \App\Models\User();
$vendor = new \Vendor\Package\Helper();

// 全局类需要加 \
$date = new \DateTime();
$array = new \ArrayObject([]);
?>

18.6 自动加载基础

手动引入每个类文件很繁琐。PSR-4 自动加载规范让 PHP 根据命名空间自动找到类文件(Composer 自动加载详见第 39 章):

<?php
// 项目结构:
// src/
//   Models/
//     User.php    -> namespace App\Models; class User {}
//   Controllers/
//     UserController.php -> namespace App\Controllers; class UserController {}
// vendor/
//   autoload.php

// composer.json 配置
{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

// 使用 Composer 自动加载
require __DIR__ . '/vendor/autoload.php';

// 直接使用类,无需手动 require
$user = new App\Models\User();
$controller = new App\Controllers\UserController();
?>

自定义自动加载

<?php
// 如果不使用 Composer,可以自己注册自动加载函数
spl_autoload_register(function (string $class): void {
    // 将命名空间分隔符转为目录分隔符
    $path = str_replace('\\', '/', $class);
    
    // 假设类文件在 src/ 目录下
    $file = __DIR__ . '/src/' . $path . '.php';
    
    if (file_exists($file)) {
        require $file;
    }
});

// 现在可以直接使用
$order = new App\Models\Order();
?>

18.7 命名空间最佳实践

<?php
// 1. 命名空间与目录结构对应(PSR-4)
// 文件: src/Http/Request.php
namespace App\Http;
class Request {}

// 2. 一行一个 use 语句(PHP 7.0+ 支持一组)
use App\Models\User;
use App\Models\Post;
use App\Services\AuthService;

// 3. 使用 use function 和 use const(PHP 5.6+)
use function App\Helpers\formatDate;
use const App\Constants\VERSION;

// 4. 全局函数在命名空间中调用要加 \
namespace App;
$time = \time();        // 正确
$str = \substr('abc', 0, 1);  // 正确
?>

来源:参考了 w3cschool「PHP 命名空间」、runoob「PHP 命名空间」、php-the-right-way「Namespaces」以及 php.net 官方文档,综合改写后所得。