CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
PHP Web 入门/课时/Composer 依赖
RawBlame
课时目录12 节

PHP Web 入门

  1. 01PHP 是什么
  2. 02基础语法
  3. 03函数与命名空间
  4. 04面向对象
  5. 05Composer 依赖
  6. 06Web 请求处理
  7. 07PDO 与 MySQL
  8. 08REST API 风格
  9. 09PHP 8 新特性
  10. 10Docker 运行 PHP
  11. 11PHP vs Java 选型
  12. 12综合练习

Composer 依赖

composer.json、vendor、PSR-4。

30 分钟

Composer 依赖

这一课你将能做到

  1. 用 composer init 和 require 管理项目依赖,看懂 composer.json 每个字段
  2. 分清 install / update / dump-autoload 三个命令的职责,正确对待 composer.lock
  3. 配置 PSR-4 自动加载,把上一课的命名空间知识接到真实工程上

为什么要学

Composer 之于 PHP,就是 Maven + Gradle 之于 Java:下载依赖、解析版本冲突、生成自动加载器,全靠它。现代 PHP 项目没有「手动下载类文件」这回事——composer require monolog/monolog 一条命令,包及其依赖自动就位,vendor/autoload.php 一行 require,全部类按需加载。国内镜像(阿里云、腾讯云)也已成熟,无需担心网络。

人话:Packagist 是「应用商店」,composer.json 是「购物清单」,composer.lock 是「已安装快照」,vendor 目录是「快递箱」。学会这套流程,你就具备了读任何现代 PHP 项目的前提。

先建立图像

Composer 的三层结构:

packagist.org(中央仓库,存元数据)
        ▲ require monolog/monolog
composer.json   ← 你声明「我要什么」
composer.lock   ← 解析后的精确版本快照(每个包的 commit hash)
vendor/         ← 实际代码 + vendor/autoload.php

与 Maven 的对应:composer.json ≈ pom.xml 的 dependencies,composer.lock ≈ 锁定版本后的 effective pom,Packagist ≈ Maven Central,vendor/ ≈ 本地仓库(但直接进项目目录)。

跟着做

步骤 1:安装 Composer 并初始化项目

# Windows:官网下载 Composer-Setup.exe;macOS/Linux 用官方安装脚本或包管理器
composer --version    # Composer 2.x

mkdir demo-app && cd demo-app
composer init

按提示填写包名、描述后生成 composer.json。也可以直接手写一个最小版本:

{
    "name": "myteam/demo-app",
    "description": "PHP 学习项目",
    "type": "project",
    "require": {
        "php": ">=8.2",
        "monolog/monolog": "^3.5"
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

"php": ">=8.2" 是对运行环境的约束——相当于 Maven 里配置的 JDK 版本门槛。

步骤 2:安装依赖并体验自动加载

composer install

生成 vendor/ 目录与 composer.lock。写入口文件 index.php:

<?php
declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';   // 整个项目唯一需要的 require

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use App\Utils\Calculator;                   // 你自己的类,同样自动加载

$log = new Logger('app');
$log->pushHandler(new StreamHandler(__DIR__ . '/app.log', Logger::INFO));
$log->info('应用启动', ['user' => 'leebf']);

echo (new Calculator())->add(2, 3), PHP_EOL;   // 5
// src/Utils/Calculator.php —— 命名空间与 PSR-4 目录严格对应
namespace App\Utils;

class Calculator
{
    public function add(int $a, int $b): int
    {
        return $a + $b;
    }
}

执行 php index.php:第三方包和你自己的类共用同一套自动加载。

步骤 3:增删依赖与版本约束

composer require symfony/var-dumper      # 增加依赖并写入 composer.json
composer remove monolog/monolog          # 移除依赖
composer show                            # 查看已装包列表

版本约束语义(重点):

^3.5    ≥3.5.0 且 <4.0.0   主版本不变,兼容升级(最常用)
~3.5.0  ≥3.5.0 且 <3.6.0   锁定到次版本,只收补丁
3.5.*   只用 3.5 分支
dev-main  开发分支(生产禁用)

^ 表示「遵循语义化版本的向后兼容区间」,等价于 npm 的 caret。

步骤 4:生产部署的正确姿势

composer install --no-dev --optimize-autoloader

--no-dev 跳过 require-dev 里的开发工具(PHPUnit、PHPStan 等);--optimize-autoloader(或 -o)把 PSR-4 映射转成 classmap,减少运行时文件探测。生产环境永远用 install 不用 update:update 会按 composer.json 重新解析版本,可能在生产机器上拉到不一致的新版本。

讲清楚要点

  1. install 与 update 的本质区别:install 严格按 composer.lock 里锁定的精确版本安装(lock 不存在时才回退解析一次);update 忽略旧 lock、重新求解依赖并重写 lock。日常加包用 composer require 包名(内部是 update 该包 + install 其余)。
  2. composer.lock 必须提交版本库:它保证团队每个人、每台 CI、每台生产机装出完全相同的依赖树。不提交 lock 等于放弃可复现构建——这是 PHP 项目最常见的事故源之一。
  3. autoload 四种方式:psr-4(主流,按命名空间映射目录)、classmap(扫描指定目录生成类名→文件映射,适合无命名空间的遗留代码)、files(每次请求强制加载的函数文件)、psr-0(已弃用)。改了映射规则记得 composer dump-autoload。
  4. require-dev 与 scripts:开发工具进 require-dev(phpstan/phpstan、phpunit/phpunit);scripts 可挂生命周期钩子(如 post-autoload-dump),对标 Maven 的 plugin 绑定。

你可能会懵的地方

  • vendor 目录要不要提交到 Git? 不提交。.gitignore 里加 vendor/,靠 composer.lock 保证可复现。vendor 是「构建产物」,提交它会让仓库膨胀且极易产生合并冲突。
  • 依赖冲突(conflict)怎么解决? Composer 求解失败会打印完整的依赖链。常见解法:升级/降级某个包、放宽版本约束(把 ^3.0 放宽到 ^2.5|^3.0 前先读该包的升级指南)、或用 composer why-not 包名 版本 定位是谁卡住了版本。
  • 国内网络慢怎么办? 配置镜像:composer config -g repos.packagist composer https://mirrors.aliyun.com/composer/。企业内网一般用 Satis 或 Private Packagist 搭私有仓库托管内部包。
  • 为什么 PHP 要把 vendor 放项目里而不是全局仓库? 项目级隔离是刻意的:不同项目可以用同一个包的不同大版本,互不干扰;部署时 vendor 随项目走。这和 Maven 共享本地仓库的策略不同,但避免了「全局升级殃及所有项目」。
  • composer require 的时候发生什么? 读取 packagist 元数据 → 连同现有依赖一起做版本求解 → 选出兼容版本集 → 更新 composer.json 与 composer.lock → 下载安装到 vendor → 重建 autoload 映射。一次 require 就是小规模的 update。

错法对照

错法问题正解
把 vendor/ 提交进 Git仓库膨胀、冲突频发.gitignore 掉 vendor,提交 lock
生产环境跑 composer update版本漂移,不可复现提交 lock,生产只 install
手动改 vendor 里的代码修 bug下次 install 被覆盖fork 上游或写补丁包(patches 插件)
版本约束写 * 或 dev-main任何版本都能装,随时炸语义化约束 ^x.y,主版本升级走专项
忘写 "php": ">=8.2" 环境约束低版本机器装出可用假象composer.json 声明 php/platform 依赖
修改 autoload 配置后不 dump-autoload新类加载不到执行 composer dump-autoload

卡点急救

  1. Your requirements could not be resolved:依赖版本无解。用报错里的依赖链定位冲突双方,调整约束或升级兜底包;composer why-not vendor/pkg 2.0 查是谁在阻止。
  2. 新增类报 Class not found:先 composer dump-autoload;仍不行则核对命名空间声明与 psr-4 映射、文件名大小写是否与类名一致。
  3. Composer detected issues in your platform:运行环境 PHP 版本或扩展不满足 require 里的 php/ext-* 约束。升级 PHP 或安装对应扩展(如 ext-pdo、ext-gd)。

面试常问

  • composer install 和 composer update 的区别? install 按 composer.lock 锁定的精确版本(含 dist 引用 hash)安装,lock 不存在时才解析一次并生成;update 忽略旧 lock 重新求解并重写 lock。团队协作与生产部署一律 install,update 只在有意识地升级依赖时执行。
  • composer.lock 的作用?要不要提交? 记录依赖树的精确版本与安装来源,保证所有环境可复现构建。必须提交版本库;部署时配合 install --no-dev --optimize-autoloader。
  • PSR-4 与 classmap 自动加载的区别与取舍? PSR-4 按命名空间规则惰性查文件,开发期加类零成本;classmap 启动时生成完整「类名→文件」映射,无文件系统探测,性能更高。实践是开发用 PSR-4、生产加 --optimize-autoloader(PHP 7.2 后 Composer 默认级别已接近优化模式)。

自测三问

  1. ^2.8 允许安装的最高版本是多少?~2.8.0 呢?
  2. 为什么生产部署命令是 install --no-dev --optimize-autoloader 而不是 update?
  3. 你的类 App\Service\OrderService 应该放在哪个文件?

小结一句话

Composer = 版本求解 + 依赖安装 + PSR-4 自动加载三合一,lock 文件保证可复现,它是 PHP 工程化的地基。

延伸

  • Composer 官方文档
  • 下一课:Web 请求处理——超全局变量、表单与会话。
加载本节练习…
← 上一课面向对象下一课 →Web 请求处理