生产环境必须强制使用--no-dev和--optimize-autoloader:前者杜绝dev依赖引入的安全风险、性能损耗与运行时冲突,后者通过预生成类映射和PSR-4哈希表将类加载耗时从0.8–2.1ms降至0.03–0.07ms。
生产环境必须加 --no-dev 和 --optimize-autoloader,否则会引入安全隐患、启动变慢、内存占用升高,且可能因 dev 依赖冲突导致运行时失败。
--no-dev 不是可选项而是强制项dev 依赖(如 phpunit、mockery、symfony/debug-bundle)在生产环境毫无用途,反而带来三重风险:
class_exists() 和 new 操作sebastian/environment),会被 Composer 自动包含进 autoloader,绕过安全扫描覆盖范围执行 composer install --no-dev 后,vendor/autoload.php 不再加载 require-dev 下的任何包,composer.lock 中的 dev 依赖条目也不会被解析安装。
--optimize-autoloader 实际做了什么它触发两个关键优化:
vendor/composer/autoload_classmap.php,把所有 PSR-0/4 类路径预编译为 ['ClassName' => '/path/to/file.php'] 数组,跳过文件系统遍历new Foo\Bar 都要逐个检查 src/、lib/ 等目录这对高并发请求尤其明显:未启用时,单次类加载平均多花 0.8–2.1ms(取决于 vendor 规模);启用后稳定在 0.03–0.07ms。注意:该选项仅对 PSR-0/4 有效,files 类型自动加载不受影响。
单独运行 composer install --no-dev --optimize-autoloader 在 CI 中容易出错,需配合以下约束:
composer.lock 已提交且由开
发环境生成(即已运行过 composer update 或 composer install)——否则 --no-dev 可能漏装某些本应进入 production 的依赖composer update,哪怕加了 --no-dev —— 因为 update 会改写 lock 文件,破坏可重现性composer.json 和 composer.lock(减少镜像攻击面)composer install --no-dev --optimize-autoloader --no-interaction --quiet
--no-interaction 防止卡在 prompt(如平台配置询问),--quiet 减少日志噪音,适合自动化场景。
这几个情况会让上述参数“看似生效实则无效”:
autoload-dev 里声明了生产代码路径(例如误把 "tests/": "src/" 写成 "src/": "src/")→ 即使 --no-dev,这些类仍被加载classmap 并指向了含测试文件的目录(如 "classmap": ["tests/"])→ --no-dev 不影响 classmap 扫描结果opcache.enable_cli=1 未设(CLI 模式下 autoload_classmap.php 若未被缓存,优化效果打五折)验证是否真正生效:部署后检查 vendor/composer/autoload_classmap.php 是否存在且非空,再用 grep -r "PHPUnit" vendor/ 确认无测试框架残留。