生产环境必须用 composer install --no-dev --optimize-autoloader --no-interaction --no-scripts,缺一不可;否则会装入 PHPUnit、PHPStan 等 dev 包,引发安全风险、性能下降、I/O 开销大、部署超时或 Class not found 错误。

生产环境必须用 composer install --no-dev --optimize-autoloader --no-interaction --no-scripts,缺一不可;否则大概率装进 PHPUnit、PHPStan、debugbar 等包,引发安全风险、性能下降甚至安装失败。
为什么只敲 composer install 就会出事
Composer 不识别“生产环境”这个概念。它只看 composer.json 里有没有 require-dev,以及你有没有明确告诉它“别装”。没加 --no-dev,它就把 phpunit/phpunit、friendsofphp/php-cs-fixer 全部拉进来——哪怕服务器上根本没装 ext-xdebug 或 git,也会卡在某个 post-install 脚本里报 sh: git: not found。
常见错误现象包括:
-
vendor/体积暴涨 40MB+,部署超时 - 线上突然报
Class 'PHPUnitFrameworkTestCase' not found(说明代码误引用了 dev 类) - 安装中途挂起,日志停在
Running post-install-cmd script
--no-dev 不是“可选开关”,而是依赖过滤链的起点
--no-dev 的作用远不止跳过 require-dev 列表里的包:
- 跳过这些包的所有传递依赖(比如
phpunit/phpunit带的sebastian/exporter) - 不注册
autoload-dev命名空间(如"Tests\": "tests/"),避免测试类意外被 autoload - 跳过所有标记为
@dev的 scripts 钩子(如post-autoload-dump里调的phpstan)
但注意:--no-dev 只在 composer.lock 文件本身不含 dev 包时才真正生效。如果 lock 文件是上次用 composer update(没加 --no-dev)生成的,那 install 仍会照单全收——此时必须先在 CI 中运行 composer update --no-dev --lock 并提交新 lock。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
为什么 --optimize-autoloader 必须和 --no-dev 一起用
只加 --no-dev 不优化,自动加载器仍走 PSR-4 动态查找,每次 new Foo() 都要遍历 file_exists() 多个路径,I/O 开销大。
--optimize-autoloader(简写 -o)会生成扁平化类映射文件 vendor/composer/autoload_classmap.php,把所有类名直接映射到文件路径,跳过目录扫描。
这两个参数必须成对出现:
- 有
--no-dev没-o→ 安全但慢 - 有
-o没--no-dev→ 快但白优化(dev 类还在 autoload 树里)
Docker 或 CI 中还要额外加 --no-interaction 和 --no-scripts
生产构建环境通常禁用 proc_open、没配好 git 路径、也不允许交互式输入——而 Composer 默认会触发这些:
-
--no-interaction:跳过私有包认证提示、license 确认等阻塞点 -
--no-scripts:禁用所有scripts钩子(如post-root-package-install、post-install-cmd),防止执行前端构建、缓存清理等非必要操作
如果项目真依赖某个脚本(比如生成配置文件),应该把它抽离到 Dockerfile 的 RUN 步骤或部署脚本中单独执行,而不是靠 Composer 自动触发。

















