PHP: 命名空间与自动加载

写小项目时 3 个类够用。但业务代码可能有 300 个类,还要用第三方库——命名空间和 Composer 就是 PHP 生态的"组织系统",让你的代码不会名字撞车。

1. 为什么需要命名空间?

PHP
<?php
// 假设你写了一个 Logger 类
class Logger {
    public function log(string $msg): void {
        echo "我的日志:{$msg}<br>";
    }
}

// 你想用一个第三方包,它也有 Logger 类
// 结果:PHP Fatal Error: Cannot redeclare class Logger
?>

命名空间解决这个问题——相当于给每个类加上"姓氏":

TEXT 📖 仅展示
没有命名空间:Logger ← 撞车!
用了命名空间:MyApp\Logger  vs  Vendor\Logger ← 不撞!

2. namespace 声明

PHP
<?php
// file: app/Utils/Logger.php
namespace App\Utils;

class Logger {
    public function log(string $msg): void {
        echo "[LOG] {$msg}<br>";
    }
}

// 使用全限定名
$log = new \App\Utils\Logger();
$log->log("程序启动");
?>

命名空间规则:


3. use — 导入类

PHP
<?php
namespace App\Controllers;

// use 导入后,直接用类名
use App\Utils\Logger;
use PDO;
use DateTime;

class UserController {
    public function index(): void {
        $log = new Logger();  // 不需要写全限定名
        $log->log("访问用户列表");
        
        $now = new DateTime();  // PHP 内置类,也可以 use
    }
}
?>

(1) use ... as — 别名

PHP
<?php
// 解决同名冲突
use App\Models\User as AppUser;
use Vendor\Cms\User as CmsUser;

$u1 = new AppUser();
$u2 = new CmsUser();
?>

4. Composer — PHP 的包管理器

Composer 之于 PHP,就像 npm 之于 Node.js,pip 之于 Python。

(1) 安装 Composer

访问 https://getcomposer.org 下载安装,然后在项目目录:

BASH
# 初始化项目
cd myphp
composer init

# 安装一个包(以常用的 .env 配置库为例)
composer require vlucas/phpdotenv

▶ 示例:composer.json 配置与自动加载

JSON
{
    "name": "myphp/demo",
    "description": "PHP学习项目",
    "require": {
        "php": ">=8.0",
        "vlucas/phpdotenv": "^5.0"
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    }
}

(2) 使用自动加载

PHP
<?php
// 只需要 require 这一个文件
require __DIR__ . '/vendor/autoload.php';

// 现在可以用 Composer 管理的所有包和自定义类
use App\Models\User;

$user = new User();
?>

5. PSR-4 自动加载

PSR-4 是 PHP 社区的自动加载标准——命名空间前缀对应目录

命名空间 对应目录 类文件路径
App\ app/ app/ 是根
App\Models\User app/Models/User.php
App\Controllers\Admin\Dashboard app/Controllers/Admin/Dashboard.php

▶ 示例:PSR-4 项目结构

TEXT 📖 仅展示
myphp/
├── app/
│   ├── Models/
│   │   └── User.php          ← namespace App\Models;
│   └── Controllers/
│       └── UserController.php ← namespace App\Controllers;
├── vendor/                   ← Composer 自动创建
│   └── autoload.php
├── composer.json
└── public/
    └── index.php
PHP
<?php
// app/Models/User.php
namespace App\Models;

class User {
    public function __construct(
        public string $name,
        public string $email
    ) {}
}
PHP
<?php
// public/index.php
require __DIR__ . '/../vendor/autoload.php';

use App\Models\User;

$user = new User("小明", "xiaoming@example.com");
echo $user->name;  // 小明
?>

6. Composer 常用命令

BASH
# 安装 composer.json 中列出的所有依赖
composer install

# 添加新依赖
composer require guzzlehttp/guzzle
composer require --dev phpunit/phpunit  # 仅开发环境

# 更新所有依赖
composer update

# 更新单独某个包
composer update guzzlehttp/guzzle

# 生成优化的自动加载器(生产环境)
composer dump-autoload -o

7. 自带类 vs 命名空间

PHP
<?php
namespace App;

// 在命名空间中调用 PHP 内置类
$date = new \DateTime();          // 根命名空间 \
$pdo  = new \PDO($dsn, $user, $pass);

// 或用 use
use DateTime, PDO;

$date = new DateTime();
$pdo  = new PDO($dsn, $user, $pass);
?>
💡 提示: 在命名空间内部,PHP 内置类必须加 \ 前缀或 use 导入。不加的话 PHP 会在当前命名空间里找(App\DateTime,根本不存在)。

❓ 常见问题

Q 命名空间一定要和文件路径一样吗?
A PSR-4 规范要求一致,但 PHP 语法上不强制。手动 require 时可以随意命名。但按规范做事,Composer 的自动加载才能工作。
Q Composer 的包安装到哪里了?
A vendor/ 目录。这个目录通常不提交到 Git(在 .gitignore 中配置)。团队成员用 composer install 自行安装。
Q composer.json 中的 ^5.0 什么意思?
A 语义化版本(SemVer)约束。^5.0 表示接受 >=5.0 且 <6.0 的版本。~5.0 表示 >=5.0 且 <5.1。

📖 小节

📝 作业

  1. 创建一个简单的项目结构:app/Models/User.phpapp/Utils/Validator.php,各自声明命名空间,在 public/index.php 中用 use 导入并使用。
  2. 安装 Composer,用 composer init 初始化项目,在 composer.json 中配置 PSR-4 自动加载。
  3. 安装一个第三方包(如 ramsey/uuid 用于生成 UUID),理解 vendor 目录和 autoload.php 的作用。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏