生产环境部署必须使用 composer install --no-dev;该命令排除 require-dev 中的包,避免引入调试工具、测试框架等安全隐患,是唯一可靠做法。

composer install 时跳过 dev 依赖的正确命令
生产环境部署必须排除 require-dev 里的包,否则可能引入调试工具、测试框架甚至安全隐患。唯一可靠的方式是加 --no-dev 参数,不加就默认全装。
-
composer install --no-dev是唯一推荐做法;composer update --no-dev同理,但生产环境不该用update - 别信
COMPOSER_NO_DEV=1环境变量——它只在部分旧版本生效,且容易被 CI/CD 脚本覆盖,行为不稳定 - 如果
composer.lock里本来就没记录 dev 包(比如之前就是用--no-dev生成的),那单纯composer install也不会装,但这属于侥幸,不能当做法
为什么 vendor/autoload.php 在 --no-dev 下仍能加载 dev 类
autoload 规则写在 composer.json 的 autoload 和 autoload-dev 里,而 --no-dev 只控制「安装哪些包」,不控制「怎么加载类」。只要某个 dev 包的类已被加载进 autoloader(比如你手动 require 过),它就能用。
- 典型陷阱:
phpunit没装,但项目里写了use PHPUnit\Framework\TestCase;,PHP 解析时直接报Class not found—— 这不是 autoloader 问题,是代码本身越界引用了 dev-only 类 - 检查方法:运行
composer dump-autoload --no-dev,它会清掉autoload-dev里的映射,让这类错误提前暴露 - CI 中建议加一步:
composer install --no-dev && composer dump-autoload --no-dev
如何确认当前环境真的没装 dev 包
光看命令不够,得验证结果。最直接的办法是查 vendor/ 目录和 composer.lock 内容。
- 执行
ls vendor/ | grep -E "phpunit|mockery|symfony\/debug"—— 这些常见 dev 包名一个都不该出现 - 打开
composer.lock,搜索"require-dev"字段,再搜"packages-dev":如果存在,说明 lock 文件生成时没带--no-dev;应该删掉 lock 文件重来 - 注意:有些包(如
symfony/console)既在require又在require-dev出现,此时它仍会被安装——这是正常行为,不用慌
CI/CD 脚本里漏掉 --no-dev 的典型表现
构建成功但线上报错,往往不是代码问题,而是环境不一致。最常踩的坑是脚本里写死了 composer install 却没加参数,或用了缓存导致复用旧 vendor。
- GitHub Actions 示例片段:
run: | composer install --no-dev --optimize-autoloader --classmap-authoritative
,三个参数缺一不可 -
--optimize-autoloader强制生成 classmap,避免运行时扫描;--classmap-authoritative告诉 autoloader「没在 classmap 里的类就一定不存在」,进一步提速并防止误加载 - 如果用 Docker,确保
composer install命令不在基础镜像的ENTRYPOINT里硬编码——那种写法改起来极难排查
--no-dev 不是可选项,是开关。漏掉它的后果不是报错,而是悄悄多装十几个包,其中某个可能监听 8080 端口、暴露调试面板、或拖慢启动速度——这些都得上线后才看得见。










