post-install-cmd在ci/cd中默认不执行,因composer v2+在composer_dev_mode=0(即生产/ci环境)下强制禁用所有xxx-cmd钩子,属安全策略而非bug;需显式调用composer run-script post-install-cmd --no-dev或改用自定义脚本名并手动触发。

CI/CD 里不能靠 post-install-cmd 自动触发脚本——它默认被禁用,必须显式调用。
为什么 post-install-cmd 在 CI 中基本不执行
Composer v2+ 默认在 COMPOSER_DEV_MODE=0(即 CI 环境)下跳过所有 xxx-cmd 钩子,这不是 bug,是安全策略:防止开发期脚本(如清缓存、生成代理类)意外污染生产构建流程。
常见现象是:本地 composer install 能打印“初始化完成”,CI 日志却完全没输出,也没报错——脚本静默跳过。
- 不加
--no-dev时,post-install-cmd可能仍执行,但这是危险的侥幸:dev 依赖混入生产环境后,class_exists('PHPUnit\Framework\TestCase')会直接 fatal - 加了
--no-dev后,钩子默认关闭;想让它跑,得额外补一句:composer run-script post-install-cmd --no-dev - 更稳妥的做法是定义独立脚本名,比如
"deploy:post-install": "php init.php",然后在 CI 步骤中明确运行:composer run deploy:post-install
composer install 必须带的三个硬性参数
漏掉任一,线上 autoload 就可能失败或性能崩塌。这不是“优化”,是 autoload 正常工作的前提。
-
--no-dev:排除require-dev里的包(如phpunit、infection),避免体积膨胀和未审计的远程调用风险 -
--optimize-autoloader:生成vendor/composer/autoload_classmap.php,把 PSR-4 映射编译成静态数组,跳过运行时file_exists()探测 -
--classmap-authoritative:强制 autoloader 相信 classmap,彻底禁用 fallback 文件系统扫描——这是防止Class not found的最后一道防线
三者必须同时出现。单独开 --optimize-autoloader 没用:PHP 仍会 fallback 查找;漏掉 --no-dev,--classmap-authoritative 反而会让 class_exists() 判定失败。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
CI 中 composer install 卡住的真正原因
不是命令写错,而是底层环境缺失隐性依赖。最常见四类问题:
-
composer.lock没提交到 Git:CI 拉下来是空的,composer install直接报错退出,不会自动生成 - PHP 扩展缺失:Alpine 镜像常缺
ext-zip或ext-openssl,导致下载失败且无明确错误,进程被 kill - PHP 版本不匹配:
composer.json写着"php": "^8.2",但 CI 用的是 8.1,部分包会被跳过,autoload 表不完整 - 内存不足:Composer 解析大型依赖图时峰值高,CI 默认限制常触发
Killed或Allowed memory size exhausted;必须在命令前加export COMPOSER_MEMORY_LIMIT=-1
缓存该缓谁?~/.composer/cache 还是 vendor/
缓存 vendor/ 是最危险的直觉错误。它与 PHP 版本、opcache.enable、大小写敏感度强耦合,缓错一次,就会随机出现 Cannot declare class 或 Class not found。
真正安全的缓存目标只有 ~/.composer/cache ——它只存 zip/dist 包,跟环境完全解耦,只由 composer.lock 哈希决定是否复用。
- GitHub Actions 示例:
path: ~/.composer/cache,key必须含${{ hashFiles('**/composer.lock') }} - GitLab CI 示例:
cache: paths: [~/.composer/cache],绝不能写vendor/ - 缓存失效最常见原因:本地手动生成新
composer.lock但没提交,导致 key 不匹配,CI 每次走冷安装
构建产物是否干净,取决于你有没有在打包前剔除 .env*、tests/、phpunit.xml ——这些细节比参数本身更容易在线上暴露问题。










