PHP 入门教程
18.3 使用
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 官方文档,综合改写后所得。