部署时必须用 composer install --locked --no-dev --optimize-autoloader --classmap-authoritative,它严格按 composer.lock 还原依赖,不解析 composer.json;漏 --no-dev 会污染生产环境,--locked 可防止 lock 异常时降级执行。

部署时执行 composer install 是为了精确还原依赖版本
它不解析 composer.json 里的任何新约束,只读 composer.lock 中记录的包名、精确版本号、dist source 和 checksum,逐字节还原 vendor 目录。哪怕你刚在 composer.json 里加了一行 "foo/bar": "^2.0",只要 composer.lock 没变,composer install 就完全无视那行——它不是“安装当前声明”,而是“回到上次锁定的状态”。
CI/CD 或生产环境用 composer update 会直接导致环境漂移
常见错误现象包括:
-
composer update在部署脚本里跑通了,但上线后php artisan报Class not found—— 实际是symfony/console被升到了 v6.4,而项目代码还调用了 v6.3 移除的私有方法 - 本地
composer update后忘了提交新的composer.lock,CI 流水线执行composer install时,因 lock 文件缺失或格式异常,悄悄 fallback 到按composer.json重生成 lock,结果装出和本地完全不同的依赖树
正确做法是在部署命令中强制加 --locked 参数:composer install --locked --no-dev --optimize-autoloader --classmap-authoritative。一旦 lock 文件异常,命令立刻失败,不给“自作主张”的机会。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
为什么 --no-dev 不是可选项,而是部署红线
漏掉 --no-dev 的后果不是报错,而是静默污染线上环境:
-
vendor/里多出phpunit、phpcs等 dev 包,自动加载器体积增大 30%+,PHP-FPM 内存占用明显升高 - 某些 dev 包自带路由或调试接口(比如
barryvdh/laravel-debugbar),若配置残留,可能意外暴露敏感信息 - Docker 构建中若把
composer install放在基础镜像层且没加--no-dev,会导致所有基于该镜像的容器都带上不该存在的包
composer install 不等于“装完就完事”
它只管 vendor 目录和 autoloader 的物理还原,但以下几件事它不做,必须人工确认或补操作:
- 不校验 PHP 版本是否满足
composer.json中config.platform.php或require.php的声明——上线前得自己php -v - 不检查扩展是否启用,比如
ext-gd或ext-redis缺失,要等到第一次请求才报错 - 不 reload opcache,如果线上开了
opcache.enable=1,改完 autoload 后得手动opcache_reset()或重启 PHP 进程 - 不处理
autoload配置变更后的 classmap 更新——改了psr-4映射或新增了老式文件,必须额外跑一次composer dump-autoload -o
真正可靠的部署,从来不是一条命令的事;composer install 只是其中最确定的一环,其余环节松动一点,整条链就不可复现。

















