ci必须用composer install而非update以确保构建可重现,需提交composer.lock、缓存~/.composer/cache、生产部署加--optimize-autoloader和--classmap-authoritative并校验php版本与扩展。

CI里必须用composer install,别碰composer update
CI不是你本地开发环境,它不负责“决定装什么”,只负责“精确还原”。一旦在CI脚本里写了composer update,lock文件就被改写,构建就失去可重现性——昨天能过的流水线,今天可能因一个monolog的patch更新而失败。
-
composer install读composer.lock,装完全一致的依赖树;composer update重解析composer.json,触发版本重选和依赖图重建 - Git仓库中必须已提交
composer.lock——CI不会帮你生成它,没这个文件,install直接报错退出 - 如果CI报
Lock file operations: 1 install, 0 updates, 0 removals却卡住,大概率是PHP扩展缺失(比如ext-zip没装),不是命令写错了
缓存~/.composer/cache,不是vendor/
缓存vendor/看似快,实则埋雷:不同PHP版本、不同平台生成的autoloader不能混用,缓存错版本会导致Class not found或Cannot declare class。真正该缓存的是Composer自己的下载包缓存目录——它跟环境无关,只跟composer.lock哈希绑定。
- GitHub Actions推荐这样写:
- name: Cache Composer packages uses: actions/cache@v4 with: path: ~/.composer/cache key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }} - GitLab CI用
cache:关键字,路径填~/.composer/cache,别写vendor - 缓存失效最常见原因:
composer.lock被意外修改(比如本地手动生成又没提交),导致key不匹配,每次走冷安装
生产部署加--optimize-autoloader和--classmap-authoritative
这两个参数不是“锦上添花”,而是生产环境autoload性能的底线。没它们,PHP每次class_exists()或自动加载都会遍历整个psr-4映射,IO开销大,还容易因符号链接或大小写问题漏类。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
--optimize-autoloader把PSR-4/PSR-0映射编译成静态数组,跳过实时扫描 -
--classmap-authoritative告诉Autoloader:“不在classmap里的类,一律不存在”,彻底禁用file_exists()试探,提速明显 - 必须配合
--no-dev一起用:dev依赖(如phpunit)不进classmap,但若代码里有class_exists('PHPUnit\Framework\TestCase')这种运行时判断,就会fatal——得改用class_exists(..., false)或先function_exists()兜底
PHP版本和扩展不匹配,composer install会静默出错
项目composer.json里写着"php": "^8.2",但CI用的是8.1?Composer不会报错,但它可能跳过某些仅支持8.2+的包(比如带match表达式的库),或者生成的autoloader在运行时报ParseError。
- CI第一步就得校验PHP版本:
php -v和composer show --platform都得检查 - Alpine镜像默认不带
ext-pdoext-zipext-xml,得显式安装,例如apk add php82-pdo php82-zip php82-dom - 用
config.platform.php锁定目标环境版本,比如composer config platform.php 8.1.25,防止本地PHP太新导致lock文件记录了高版本特有依赖
最容易被忽略的一点:私有包认证失败时,错误日志往往只显示Could not fetch,根本看不出是auth.json没配好。别急着提交vendor,先确认CI是否通过composer config http-basic.repo.example.com $USERNAME $TOKEN动态注入凭据——硬编码auth.json在Git里是安全红线。










