生产环境误装phpunit或var-dumper必然报错、膨胀体积、暴露调试入口,根本原因是未强制使用composer install --no-dev,且未同步更新composer.lock与autoload-dev规则。

生产环境装了 phpunit/phpunit 或 symfony/var-dumper,不是“可能出问题”,是必然报错、体积膨胀、暴露调试入口——根本原因不是 Composer 不懂环境,而是你没管住 composer install 的参数和 composer.lock 的生成逻辑。
require 和 require-dev 的本质区别不是“环境”,而是“是否参与运行时”
require 里的包,PHP 运行时会 new、use、调用函数;缺了直接 Fatal error 或 Class not found。require-dev 里的包,只在你敲命令时起作用:比如跑 ./vendor/bin/phpunit、执行 phpstan analyse、或本地 bin/console cache:clear 里调用了调试类——但这些类绝不会被线上请求链路加载。
常见误判:
- 把
symfony/var-dumper放进require-dev,结果线上开了 debug 模式,dump()调用失败,500 报错 - 测试代码写了
new Mockery\MockInterface(),但没在autoload-dev里声明tests/目录,CI 报Class not found -
composer require --dev phpunit/phpunit少打一个空格写成composer require-dev phpunit/phpunit,结果误装进require,生产镜像白胖 20MB
部署时 --no-dev 不是可选项,是强制开关
composer install 默认照着 composer.lock 装所有记录的包,不管它在 require 还是 require-dev 里。不加 --no-dev,require-dev 包照装不误——Composer 不看 APP_ENV=prod,也不读服务器 hostname,它只认命令参数。
实操要点:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- Dockerfile 里必须写死:
composer install --no-dev --optimize-autoloader - GitHub Actions / GitLab CI 缓存 key 必须包含
--no-dev标志,例如:composer-${{ hashFiles('**/composer.lock') }}-${{ env.COMPOSER_FLAGS || '--no-dev' }} - CI 流水线跑测试阶段要用完整安装:
composer install && ./vendor/bin/phpunit;但构建生产镜像那步,必须切回--no-dev - 如果
composer.lock本身含require-dev包记录,composer install --no-dev也无效——得先composer update --no-dev --lock提交新 lock
autoload-dev 和 require-dev 完全不是一回事
autoload-dev 是自动加载规则,只影响路径注册(如 tests/、stubs/);require-dev 是包声明,决定是否下载解压安装。两者常被混为一谈。
关键事实:
- 没装
require-dev包,autoload-dev配置再全也没用——类文件根本不存在 -
composer dump-autoload --no-dev才会剔除autoload-dev映射;漏掉这步,vendor/autoload.php仍含测试路径,可能引发 autoload 冲突 -
autoload-dev不是给 PHPUnit 自己用的,是给你写测试时能直接use App\Tests\FooTest用的 - 别在
autoload.files里写"config/{$_ENV['APP_ENV']}.php"——Composer 不解析 PHP 变量,会直接报错
判断一个包是不是真能放进 require-dev 的三原则
不能只看包名或用途,得查它是否被运行时代码间接引用:
- 对每个
require-dev包,执行grep -r "vendor/name" src/ tests/,确认src/下无任何use或new - 它是否只出现在
tests/、phpstan/phpstan、php-cs-fixer这类命令行工具里 - 它是否被框架条件加载但没做
class_exists()判断(比如 Laravel 的AppServiceProvider中硬编码加载调试辅助函数)
最常被忽略的是:某些日志处理器、上下文装饰器,表面在 require-dev,实际被异常捕获逻辑调用——这种就不是纯 dev 依赖,必须挪回 require。










