发布于2026-07-06 阅读(0)
扫一扫,手机访问

核心原则只有一条:CI 里必须跑 composer install,绝对禁用 composer update。
composer update 是危险操作它会直接改写 composer.lock 文件。哪怕只是 monolog/monolog:2.10.0 → 2.10.1 这种看似无害的 patch 级升级,也可能触发测试覆盖不到的边界逻辑。结果往往是:
Class not found 或 Method not found 错误,测试通过但线上直接崩溃vendor/ 目录内容不一致,导致同一个 commit 在不同环境下的行为截然不同composer install 时行为变得不可预测CI 不是做依赖决策的地方,它唯一该做的事就是“还原”——还原出和本地开发环境、生产环境完全一致的依赖树。就这么简单。
composer install 必须有 composer.lock 才能运行如果项目没提交 composer.lock,那么 composer install 实际上会退化为 composer update 的行为(并生成一个新的 lock 文件),这放在生产服务器上就是定时冲击波。所以 CI 脚本开头必须加一道校验:
composer validate --strict
这个命令会检查 composer.json 和 composer.lock 是否匹配。如果发现不匹配,直接失败,别想着用 --ignore-platform-reqs 强行绕过。本地开发的话,建议配一个 pre-commit 钩子:composer install --dry-run,提前发现 lock 过期或不一致的问题。
~/.composer/cache,别缓存 vendor/缓存 vendor/ 看起来能提速,但实际是个坑。不同 PHP 版本、不同扩展(比如 ext-apcu 是否开启)、甚至不同的大小写敏感系统,生成的 autoload 文件都不兼容。缓存一次,下次就可能随机出现 Cannot declare class 或 include(): Failed opening 的错误。
真正安全的做法是缓存 Composer 自己的下载缓存目录,它只存 zip 和 dist 包,跟环境完全解耦:
path: ~/.composer/cache,key 必须包含 ${{ hashFiles('**/composer.lock') }}cache: paths: [~/.composer/cache],千万别写 vendor/缓存失效最常见的原因是什么?是本地手动生成了新的 composer.lock 但没提交,导致 key 不匹配,CI 每次都得走冷安装。
--no-dev --optimize-autoloader --classmap-authoritative这三个参数不是可选项,它们是 autoload 性能的底线:
--no-dev:跳过 require-dev,减小镜像体积,避免加载测试工具类--optimize-autoloader:把 PSR-4 映射编译成静态数组,避免每次自动加载都执行 file_exists() 探测--classmap-authoritative:告诉 Autoloader “不在 classmap 里的类,一律不存在”,彻底跳过文件系统查找不加这些参数会怎样?PHP 每次自动加载都要遍历映射、试探路径,IO 开销大不说,还容易因为符号链接、大小写问题或 opcache 失效而漏类。
最后,聊一个最容易被忽略的点:离线部署时,composer.lock 一致并不等于代码的字节一致。不同时间、不同镜像源下载的 dist 包,它们的 SHA256 可能不同,composer install 在校验时就会失败。真要离线部署,靠传完整的 vendor/ 目录比只传 lock 文件可靠得多。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8