新项目首次拉代码、上线部署必须用 composer install,本地开发加依赖才用 update;install 读 lock 文件确保一致性,update 重解析 json 升级版本。

composer install 和 composer update 到底该用哪个?composer install 只读 composer.lock,装里面写死的版本;composer update 会重新解析 composer.json,升级到满足约束的最新兼容版——**新项目首次拉代码、上线部署必须用 install,本地开发加依赖才用 update**。
常见错误现象:
- 团队里有人运行了 composer update 后提交了新的 composer.lock,其他人 install 出来行为不一致,但没人意识到是 lock 文件被悄悄改了
- 直接删掉 vendor 和 composer.lock,只留 composer.json 就跑 update,结果装了一堆新版包,引发兼容性崩溃
使用场景判断很简单:
- 你刚 clone 一个别人写的项目 → 无脑
composer install - 你要加一个新包,比如日志组件 → 先
composer require monolog/monolog(它自动update并更新 lock) - 你想把所有包升到最新小版本(如 2.1.3 → 2.1.9)→
composer update --with-dependencies,别裸跑update
为什么 vendor/autoload.php 是唯一要引入的文件?
Composer 不是“复制一堆 .php 文件进来”就完事,它生成的 vendor/autoload.php 是整个自动加载系统的入口,背后按 PSR-4 规则把命名空间映射到物理路径。你手动 require 某个类文件,等于绕过 Composer 的加载逻辑,下次换版本或换结构就直接报错。
容易踩的坑:
- 在入口文件里写 require 'vendor/autoload.php';,但路径写成 ./vendor/autoload.php 或 ../vendor/autoload.php,一挪目录就挂
- 误以为 autoload.php 是“可选的”,自己手写 require_once 'vendor/monolog/monolog/src/Monolog/Logger.php';,结果 Monolog 内部又依赖其他类,全得手动补
- 用了自定义 autoload 配置但没执行 composer dump-autoload,改了命名空间映射却不生效
正确做法就一条:
- 所有 PHP 入口(如
index.php、cli.php)第一行必须是require <strong>DIR</strong> . '/vendor/autoload.php';,用<strong>DIR</strong>保绝对路径安全
国内网络下 composer install 卡在 “Loading composer repositories” 怎么办?
这是 Packagist 官方源(https://packagist.org)被墙导致的典型现象,不是你网络断了,也不是 Composer 坏了。官方源走的是境外 CDN,国内直连基本超时。
解决方式只有换镜像源,且必须全局或项目级配置,不能靠“多试几次”。
- 全局换(推荐):composer config -g repo.packagist composer https://packagist.phpcomposer.com(注意:此镜像已停用)→ 改用清华源:composer config -g repo.packagist composer https://packagist.phpcomposer.com 实际应为 composer config -g repo.packagist composer https://packagist.mirrors.ustc.edu.cn
- 临时换(适合 CI/CD):composer install --repository=https://packagist.mirrors.ustc.edu.cn
- 验证是否生效:composer config -g repo.packagist 应输出镜像地址,而不是 packagist.org
别信“清 DNS 缓存”“换代理”这种玄学操作——Composer 请求不走系统 DNS,它硬编码了源地址。
composer.json 里 require 和 require-dev 的区别真那么重要?
重要。它不只是语义区分,直接影响生产环境的安全和体积。
require 里的包,composer install --no-dev 也会装;require-dev 里的,比如 phpunit/phpunit、friendsofphp/php-cs-fixer,只在开发机上需要,上线时必须排除。
常见错误:
- 把测试工具写进 require,导致线上容器多装 50MB 无用代码,还可能暴露调试接口
- 用 composer require xxx --dev 加包后,忘了检查 composer.json 是否真的进了 require-dev 区块(有时因已有 lock 文件冲突会写错位置)
- CI 脚本里漏掉 --no-dev,导致构建产物包含开发依赖,扫描出一堆高危 CVE
关键原则:
- 运行时真正需要的类(如数据库驱动、HTTP 客户端)→
require - 仅用于写代码、测代码、格式化代码的工具 →
require-dev - 线上部署命令必须带
--no-dev --optimize-autoloader --classmap-authoritative,三者缺一不可
有些团队把 autoload-dev 和 require-dev 混为一谈,其实前者只影响自动加载路径,后者才决定安装行为——这点连不少老手都会忽略。










