一、回顾与本篇目标
上一篇你学会了 PHP 面向对象编程——类、对象、继承、接口、命名空间。你的代码现在可以用面向对象的方式来组织了——把数据和操作数据的方法封装在类里,通过继承和接口实现代码复用。
但有一个实际问题还没解决:当项目中有几十个甚至上百个类文件时,你需要手动写几十行 require_once 来引入每个类文件。这不仅繁琐,而且容易出错——如果文件名或路径变了,所有引入它的地方都需要修改。更麻烦的是,如果你使用第三方库(比如发送邮件的库、处理图片的库、生成 PDF 的库),你需要手动下载它们的代码,手动引入它们的类文件,手动管理它们之间的依赖关系。
这就是 Composer 要解决的问题。Composer 是 PHP 的包管理器——相当于 Node.js 的 npm、Python 的 pip、C/C++ 的 vcpkg。它帮你做两件核心的事:
- 管理依赖:自动下载和更新第三方库,处理库与库之间的依赖关系。
- 自动加载类:你只需要声明”这个类在哪个文件里”,Composer 就会在你使用类的时候自动引入对应的文件。不需要写任何
require_once。
现代 PHP 开发中,Composer 是必备工具。Laravel、Symfony、WordPress 的现代开发流程都依赖 Composer。学会 Composer,你就打开了 PHP 生态的大门——成千上万个高质量的开源库都可以通过 Composer 一键安装使用。
本篇的目标:
- 理解 Composer 是什么、为什么需要它
- 学会安装 Composer
- 学会用 Composer 安装和管理第三方库
- 理解 PSR-4 自动加载规范
- 学会配置 Composer 自动加载自己的类
- 了解
composer.json和composer.lock的区别
二、没有 Composer 的时代:手动引入的噩梦
先看看没有 Composer 时,项目是怎么组织的:
<?php
// 手动引入所有需要的类文件
require_once 'app/Database.php';
require_once 'app/Models/User.php';
require_once 'app/Models/Article.php';
require_once 'app/Controllers/UserController.php';
require_once 'app/Controllers/ArticleController.php';
require_once 'app/Middleware/AuthMiddleware.php';
require_once 'app/Helpers/StringHelper.php';
require_once 'app/Helpers/DateHelper.php';
require_once 'vendor/mailer/Mailer.php';
require_once 'vendor/pdf/PDFGenerator.php';
require_once 'vendor/cache/Cache.php';
// ... 几十行 require_once ...
// 现在才能开始写业务逻辑
$userController = new App\Controllers\UserController();
?>
这段代码有几个问题:
- 繁琐:每新建一个类,就要加一行
require_once。项目有 50 个类就要写 50 行。 - 容易出错:文件名和路径必须完全匹配。如果把
User.php改名为UserModel.php,所有引入它的地方都要改。 - 不必要的加载:无论请求是否需要这个类,所有文件都会被加载。如果一个请求只需要
UserController,为什么要把PDFGenerator也加载进来? - 依赖管理困难:如果
Mailer库又依赖了Socket库,你需要手动下载Socket库,然后手动保证引入顺序正确。
Composer 一次性解决所有这些问题。
三、安装 Composer
3.1 Windows 安装
- 打开浏览器,访问
https://getcomposer.org/download/。 - 下载 Composer-Setup.exe。
- 运行安装程序。安装过程中,它会自动找到你系统上的 PHP 路径。如果没有自动找到,手动选择
php.exe所在目录(比如C:\php\php.exe)。 - 一路点击 Next,完成安装。
3.2 Mac 安装
推荐用 Homebrew:
brew install composer
或者手动安装(如果不用 Homebrew):
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
sudo mv composer.phar /usr/local/bin/composer
3.3 Linux 安装(Ubuntu/Debian)
sudo apt update
sudo apt install composer
3.4 验证安装
打开终端,输入:
composer --version
如果出现类似 Composer version 2.8.x 的版本号,说明安装成功。
四、Composer 的核心文件
4.1 composer.json:项目的依赖声明
composer.json 是 Composer 的配置文件,放在项目根目录。它告诉 Composer:这个项目叫什么名字、依赖哪些第三方库、用什么 PHP 版本、以及如何自动加载类。
一个典型的 composer.json:
{
"name": "myapp/my-blog",
"description": "一个简单的博客系统",
"type": "project",
"require": {
"php": ">=8.1",
"monolog/monolog": "^3.0",
"phpmailer/phpmailer": "^6.9"
},
"require-dev": {
"phpunit/phpunit": "^11.0"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
关键字段说明:
| 字段 | 含义 | 示例 |
|---|---|---|
name |
项目名称(格式:组织名/项目名) | "myapp/my-blog" |
require |
生产环境依赖(线上运行必需的库) | "monolog/monolog": "^3.0" |
require-dev |
开发环境依赖(只在本地开发时使用的库,如测试框架) | "phpunit/phpunit": "^11.0" |
autoload |
自动加载配置(告诉 Composer 如何找到你的类文件) | "psr-4": {"App\\": "src/"} |
版本号中的 ^ 符号:^3.0 表示兼容 3.0 到 3.x 的所有版本,但不包括 4.0。这允许你接收 bug 修复和次要功能更新,但不会自动升级到下一个可能破坏兼容性的大版本。
4.2 composer.lock:锁定精确版本
第一次执行 composer install 时,Composer 会生成 composer.lock 文件。这个文件记录了你实际安装的每个库的精确版本号。把它提交到 Git,确保团队所有成员和服务器上安装的是完全相同的依赖版本。
composer.json 和 composer.lock 的分工:
composer.json:声明”我需要什么库,版本范围是什么”(松散的约束)。composer.lock:记录”上次安装的具体是什么版本”(精确的锁定)。
五、安装第一个第三方库
我们用 Monolog 来演示——这是 PHP 最流行的日志记录库,被 Laravel、Symfony 等框架广泛使用。
5.1 初始化项目
# 创建项目目录
mkdir my-composer-demo
cd my-composer-demo
# 初始化 Composer 项目(交互式,一路回车使用默认值即可)
composer init
或者直接手动创建 composer.json:
{
"name": "demo/composer-demo",
"description": "学习 Composer 的演示项目",
"require": {}
}
5.2 安装 Monolog
composer require monolog/monolog
这个命令做了三件事:
- 从
https://packagist.org(PHP 的官方包仓库)下载 Monolog 及其所有依赖。 - 更新
composer.json,在require中添加 Monolog。 - 生成或更新
composer.lock,锁定精确版本。
安装完成后,项目结构变成:
my-composer-demo/
├── composer.json ← 你编辑的配置文件
├── composer.lock ← Composer 生成的版本锁定文件
├── vendor/ ← 所有第三方库的代码
│ ├── autoload.php ← Composer 生成的自动加载入口
│ ├── monolog/ ← Monolog 的代码
│ └── psr/ ← Monolog 依赖的 PSR 接口
└── index.php ← 你的业务代码
vendor 文件夹:所有第三方库的代码都在这里。它相当于 Node.js 的 node_modules、Python 的 site-packages。永远不要手动修改 vendor 里的任何文件——它们是 Composer 管理的,composer update 会覆盖你的修改。把 vendor 加入 .gitignore——不提交到版本控制,团队成员通过 composer install 自行安装。
5.3 使用 Monolog 写日志
<?php
// index.php
// 引入 Composer 的自动加载器(只需要这一行!)
require_once __DIR__ . '/vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// 创建日志记录器
$log = new Logger('my-app');
$log->pushHandler(new StreamHandler(__DIR__ . '/app.log', Logger::WARNING));
// 记录不同级别的日志
$log->info('这是一条信息日志');
$log->warning('这是一条警告日志');
$log->error('这是一条错误日志', ['user_id' => 123, 'action' => 'login']);
echo "日志已写入 app.log";
?>
关键点:只需要一行 require_once __DIR__ . '/vendor/autoload.php';,就可以使用所有通过 Composer 安装的类。不需要手动写任何 require_once 引入 Monolog 的文件。
六、Composer 常用命令
| 命令 | 作用 | 对应 npm 命令 |
|---|---|---|
composer install |
根据 composer.lock 安装所有依赖(部署时使用) |
npm ci |
composer require 库名 |
安装一个库并添加到 composer.json |
npm install 库名 |
composer require --dev 库名 |
安装到开发环境依赖(不会部署到生产环境) | npm install --save-dev 库名 |
composer update |
更新所有依赖到符合 composer.json 的最新版本 |
npm update |
composer remove 库名 |
卸载一个库并从 composer.json 中移除 |
npm uninstall 库名 |
composer dump-autoload |
重新生成自动加载文件(修改了 autoload 配置后使用) | (无直接对应) |
install 和 update 的区别很重要:
composer install:根据composer.lock中锁定的精确版本安装。不会升级任何库。适合部署到生产环境——确保服务器上安装的版本和你在本地测试的版本完全一致。composer update:根据composer.json中声明的版本范围,下载最新符合要求的版本,然后更新composer.lock。适合在本地开发时升级依赖——比如你想把 Monolog 从 3.2 升级到 3.5。
新手容易犯的错误:在服务器上执行 composer update,结果把一个库从 3.2 升级到了 3.5,而 3.5 引入了一个 bug,导致线上服务崩溃。部署时永远用 composer install。
七、自动加载自己的类
Composer 不仅能加载第三方库,还能自动加载你自己写的类。你需要遵循 PSR-4 自动加载规范——这是 PHP 社区制定的标准,规定了”命名空间的前缀对应文件目录”。
7.1 PSR-4 规范
PSR-4 的核心规则只有一条:命名空间的前缀对应文件目录,类名对应文件名。
举个例子:
// 命名空间:App\Models
// 类名:User
// 完整类名:App\Models\User
// 文件路径:src/Models/User.php
// 命名空间:App\Controllers\Admin
// 类名:DashboardController
// 完整类名:App\Controllers\Admin\DashboardController
// 文件路径:src/Controllers/Admin/DashboardController.php
你在 composer.json 中配置命名空间前缀到目录的映射:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
这行配置的意思是:所有以 App\ 开头的命名空间,去 src/ 目录下找对应的文件。
配置好之后,执行:
composer dump-autoload
告诉 Composer 重新生成自动加载文件。之后就可以直接使用 use App\Models\User; 了——Composer 会自动引入 src/Models/User.php。
7.2 完整的项目示例
项目结构:
my-app/
├── composer.json
├── vendor/
├── src/
│ ├── Models/
│ │ └── User.php
│ └── Controllers/
│ └── UserController.php
├── public/
│ └── index.php ← 前端入口
└── app.log
composer.json:
{
"name": "demo/my-app",
"require": {
"monolog/monolog": "^3.0"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
src/Models/User.php:
<?php
namespace App\Models;
class User {
public function __construct(
private string $name,
private string $email
) {}
public function getName(): string {
return $this->name;
}
public function getEmail(): string {
return $this->email;
}
}
src/Controllers/UserController.php:
<?php
namespace App\Controllers;
use App\Models\User;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
class UserController {
private Logger $log;
public function __construct() {
$this->log = new Logger('user-controller');
$this->log->pushHandler(new StreamHandler(__DIR__ . '/../app.log', Logger::INFO));
}
public function show(int $id): void {
$user = new User('张三', 'zhangsan@example.com');
$this->log->info("显示用户 ID: {$id}");
echo "用户:{$user->getName()} ({$user->getEmail()})";
}
}
public/index.php:
<?php
// 只需要这一行,所有类都能自动加载
require_once __DIR__ . '/../vendor/autoload.php';
use App\Controllers\UserController;
$controller = new UserController();
$controller->show(1);
执行:
cd my-app
composer install # 安装第三方依赖
composer dump-autoload # 生成自动加载文件
php public/index.php # 运行
输出:用户:张三 (zhangsan@example.com)
关键点:index.php 只需要引入 vendor/autoload.php 这一行。之后使用 use 引入的任何类——不管是自己写的 App\Models\User 还是第三方库的 Monolog\Logger——Composer 都会自动找到对应的文件并加载。
八、autoload 的三种方式
PSR-4 是 Composer 中最常用的自动加载方式,但它不是唯一的方式。Composer 还支持两种方式:
| 方式 | 适用场景 | 配置示例 |
|---|---|---|
| PSR-4 | 遵循命名空间规范的类(最常用) | "App\\": "src/" |
| Classmap | 不遵循命名规范的旧代码、单一文件 | "classmap": ["lib/", "legacy/"] |
| Files | 需要每次请求都加载的全局函数文件 | "files": ["app/helpers.php"] |
Classmap:Composer 会扫描指定目录下的所有 .php 文件,建立一个”类名 → 文件路径”的映射表。即使这些类没有遵循 PSR-4 命名规范,也能被自动加载。
{
"autoload": {
"classmap": ["lib/", "legacy/"]
}
}
Files:指定一些 PHP 文件,它们会在每次请求时被自动加载。适合存放全局辅助函数。
{
"autoload": {
"files": ["app/helpers.php"]
}
}
<?php
// app/helpers.php —— 全局辅助函数
function view(string $name, array $data = []): void {
extract($data);
require __DIR__ . "/views/{$name}.php";
}
function config(string $key, $default = null) {
// 读取配置文件...
}
配置之后,view() 和 config() 函数就可以在项目的任何位置直接使用,不需要 use 或 require_once。
九、Packagist:PHP 的包仓库
https://packagist.org 是 PHP 官方的公共包仓库。当你执行 composer require monolog/monolog 时,Composer 会去 Packagist 上搜索这个包,下载它的代码,同时下载它依赖的其他包。
Packagist 上有超过 40 万个 PHP 包,覆盖了几乎所有常见的需求:
- 日志:monolog/monolog
- 邮件:phpmailer/phpmailer
- 图片处理:intervention/image
- PDF 生成:dompdf/dompdf、mpdf/mpdf
- Excel 读写:phpoffice/phpspreadsheet
- HTTP 客户端:guzzlehttp/guzzle
- 测试框架:phpunit/phpunit
- 加密:defuse/php-encryption
- 验证:respect/validation
- 数据库迁移:robmorgan/phinx
需要某个功能时,先去 Packagist 搜索,大概率已经有现成的优质库可以用。
十、Composer 脚本:自动化常见任务
Composer 可以在特定时机自动执行脚本——比如安装依赖后生成配置文件、更新依赖后清理缓存。
{
"scripts": {
"post-install-cmd": [
"php -r \"echo '依赖安装完成!';\""
],
"post-update-cmd": [
"php bin/clear-cache.php"
],
"test": [
"phpunit"
],
"serve": [
"php -S localhost:8080 -t public/"
]
}
}
之后可以执行:
composer test # 运行 PHPUnit 测试
composer serve # 启动内置开发服务器
composer test 等价于 npm test,都是运行项目中定义的测试脚本。
十一、Composer 和 npm 的对比
如果你之前跟过《后端零基础入门》用过 npm,这张对比表帮你快速理解 Composer:
| 功能 | npm (Node.js) | Composer (PHP) |
|---|---|---|
| 包管理文件 | package.json |
composer.json |
| 版本锁定文件 | package-lock.json |
composer.lock |
| 依赖安装目录 | node_modules/ |
vendor/ |
| 安装依赖 | npm install |
composer install |
| 添加新依赖 | npm install 库名 |
composer require 库名 |
| 更新依赖 | npm update |
composer update |
| 开发依赖 | --save-dev |
--dev |
| 公共包仓库 | npmjs.com |
packagist.org |
| 自动加载入口 | 无需(Node.js 有内置的模块解析) | vendor/autoload.php |
两者的核心理念完全一致——声明依赖、锁定版本、自动加载。如果你用过 npm,Composer 几乎可以零学习成本上手。
十二、本篇动手练习
练习 1:创建 Composer 项目并安装库
创建一个新目录,用 composer init 初始化项目。安装 phpmailer/phpmailer 库,写一个简单的 PHP 脚本来发送一封测试邮件(可以使用 Mailtrap 等测试邮件服务,或者只是创建一个 PHPMailer 对象并输出一些属性来验证安装成功)。
练习 2:配置 PSR-4 自动加载
创建一个项目,结构如下:
project/
├── composer.json
├── public/
│ └── index.php
└── src/
├── Models/
│ └── Product.php
└── Services/
└── Cart.php
在 composer.json 中配置 PSR-4 自动加载。在 index.php 中通过 Composer 自动加载来使用 Product 和 Cart 类。
练习 3:使用全局辅助函数
在练习 2 的基础上,创建 app/helpers.php 文件,包含两个全局辅助函数:dd($var)(var_dump 后 die)和 base_path($path)(返回项目根目录拼接后的绝对路径)。在 composer.json 中用 files 方式加载这个文件。在 index.php 中测试这两个函数。
练习 4:重构之前的用户管理系统
把之前第七篇或第九篇中写的用户管理系统用 Composer 重写。创建合理的命名空间结构(如 App\Models\User、App\Controllers\UserController),用 PSR-4 自动加载,用 Monolog 记录日志。确保不需要任何 require_once 语句。
十三、本篇小结
这一篇你学会了现代 PHP 开发的必备工具——Composer:
- Composer 是什么:PHP 的包管理器,相当于 npm(Node.js)、pip(Python)。解决依赖管理和自动加载两大核心问题。
- composer.json 和 composer.lock:前者声明依赖范围和自动加载规则,后者锁定精确版本。
- 安装第三方库:
composer require 库名。所有库下载到vendor/目录。只需要一行require_once 'vendor/autoload.php'就能使用所有库。 - PSR-4 自动加载:命名空间前缀对应文件目录。在
composer.json中配置"App\\": "src/",之后use App\Models\User;会自动引入src/Models/User.php。 - 其他加载方式:Classmap(扫描目录建立映射)、Files(每次请求都加载的全局函数文件)。
- Composer 脚本:在
scripts中定义自动化任务,如composer test运行测试、composer serve启动开发服务器。
Composer 是现代 PHP 开发的起点。学会了 Composer,你就能使用 PHP 生态中成千上万个高质量的开源库,也能用面向对象的方式组织自己的代码,为接下来学习 Laravel 等框架打下坚实的基础。
下一篇预告
下一篇是《PHP 零基础入门》的终篇——《回顾与进阶——你的 PHP 学习路线图》。我们将总结本系列学过的所有内容,对比面向过程 vs 面向对象的写法,介绍 Laravel 框架的核心理念,并给出后续的学习建议。
PHP 零基础入门,每周更新。













暂无评论内容