生产环境必须用 composer install --no-dev --optimize-autoloader,否则会引入无用开发依赖、增大安全风险,并因未优化自动加载导致 I/O 开销高、启动慢;二者需同时使用才有效。

生产环境用 composer install --no-dev --optimize-autoloader 是必须的,不是可选项——它直接决定应用启动速度和内存占用。
为什么不能只用 composer install 上线
默认不加参数的 composer install 会装 require-dev 里的包(比如 phpunit、symfony/debug-bundle),这些在生产环境完全无用,还可能引入安全风险或冲突。更关键的是:自动加载器没优化,每次 class_exists() 或 new 一个类都要遍历一堆文件路径,PHP 要反复 stat(),I/O 开销明显。
-
--no-dev:跳过require-dev,删掉 dev-only 的 autoload 规则(比如psr-4到tests/) -
--optimize-autoloader(简写-o):把 PSR-4/PSR-0 映射转成静态数组,生成vendor/composer/autoload_classmap.php,跳过文件扫描 - 二者必须同时用;只用
--no-dev不优化,autoload 还是慢;只用--optimize-autoloader不去 dev 包,反而让 classmap 更大
composer install 在部署脚本里怎么写才可靠
部署脚本里不能依赖本地 composer.lock 是否存在或是否最新——CI/CD 流水线里常出现 lock 文件没提交、或开发机上手动 run 了 composer update 却没 commit 导致线上行为不一致。
- 务必先
git checkout到目标 tag/branch,再执行composer install,确保 lock 文件和代码版本匹配 - 加
--no-interaction(-n)避免卡在 prompt(比如问是否启用 plugin) - 加
--prefer-dist:优先下 zip 包而非 git clone,更快更稳定(尤其网络差时) - 完整命令建议:
composer install --no-dev --optimize-autoloader --no-interaction --prefer-dist - 如果部署机没装 Composer,别用
curl -sS https://getcomposer.org/installer | php动态下载——有中间人风险;应提前打包好composer.phar并校验 SHA256
常见报错和对应解法
Class XXX not found 不一定是 autoloader 没生效,很可能是优化后暴露了原本被“侥幸”绕过的错误。
-
Class not found+ 用了--optimize-autoloader→ 检查该类是否在autoload或autoload-dev里声明,--no-dev后autoload-dev的规则全失效 -
Plugin disabled报错 → 某些插件(如hirak/prestissimo)在 PHP 8+ 或某些 SAPI 下不兼容,加--no-plugins临时绕过(长期应升级或换插件) -
Failed to download YYY→ 部署机 DNS 或网络策略限制 packagist.org,设COMPOSER_REPO_PACKAGIST=https://packagist.phpcomposer.com(国内镜像)或自建私有 repo - CI 环境提示
Could not scan for classes→composer dump-autoload手动触发一次 classmap 生成,再install,比等 install 自动做更可控
性能差异到底有多大
一个中等规模 Laravel 应用(约 300 个 composer 包),未优化 autoload 时,php -r "echo class_exists('App\Http\Controllers\HomeController') ? 'ok' : 'fail';" 平均耗时 12–18ms;开启 --optimize-autoloader 后降到 0.3–0.6ms。对 CLI 命令影响小,但对 FPM worker 初始化、每个请求的 autoloading 累积起来就是百毫秒级差异。
- classmap 体积会变大(比如从 2MB 到 8MB),但这是内存换 CPU 和 I/O,值
- PHP 7.4+ 支持 opcache.preload,此时 classmap + preload 效果叠加,启动时间再降 30%+
- 别在本地开发时总开
--optimize-autoloader:改了类名或 namespace 后要手动dump-autoload,否则找不到新类
最常被跳过的一步是验证 classmap 是否真生成了——上线后跑一遍 ls vendor/composer/autoload_classmap.php,空文件或不存在,说明优化根本没生效。











