require里的包是运行时刚性依赖,缺则直接崩溃;require-dev里的包仅用于开发测试命令,不参与线上请求链路,部署必须显式加--no-dev否则会混入生产环境。

require里的包,线上缺了就直接崩
require声明的是运行时刚性依赖:只要代码里出现new、use或框架配置中引用了它的类,就必须进require。比如guzzlehttp/guzzle被控制器用来发HTTP请求,monolog/monolog被日志门面调用,漏装就会500。
常见错误现象:
-
Class not found报错出现在线上,但本地正常——大概率是把本该在require的包错放require-dev -
symfony/var-dumper进了require-dev,debug模式开着却调不到dump(),因为类根本没装 -
laravel/framework被挪到require-dev,容器启动直接失败
判断标准很简单:grep -r "use.*Package" . 或 grep -r "new Package" .,只要匹配到业务代码里,就必须进require。
require-dev不是“开发环境开关”,而是“不参与运行时”的声明
require-dev里的包,比如phpunit/phpunit、phpstan/phpstan、mockery/mockery,只在你敲命令时才起作用——跑测试、做静态分析、生成桩代码。它们不会、也不该被任何线上请求链路加载。
关键事实:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- Composer不读
APP_ENV,不看服务器hostname,只认--no-dev这个参数 -
composer install --no-dev后,vendor里根本没有require-dev的包,autoload.php里也不会注册它们的classmap -
composer require-dev phpunit/phpunit是无效命令——正确写法是composer require --dev phpunit/phpunit,少个空格就误进require
autoload-dev不是给require-dev包用的
这个名字极具误导性。autoload-dev的作用,是当项目本地执行过完整composer install(即装了require-dev包)时,把tests/、stubs/这些目录也加进自动加载规则,方便你写测试时直接use AppTestsFooTest。
但它跟require-dev包自身的加载无关。也就是说:
- 即使
autoload-dev写了"psr-4": {"Tests\": "tests/"},如果生产环境只跑--no-dev,tests/目录根本不会被加载 - 如果你的测试类用了
MockeryMockInterface,除了把mockery/mockery放require-dev,还得确保autoload-dev包含对应路径,否则CI里Class not found -
autoload-dev配置再全,也不能让require-dev包在--no-dev环境下“复活”
Dockerfile和CI里漏掉--no-dev就是线上翻车
部署阶段不显式加--no-dev,等于没分require和require-dev。线上镜像会多出几十MB、启动变慢、还可能暴露调试接口或引入CVE。
实操要点:
- Dockerfile里必须写死:
composer install --no-dev --optimize-autoloader - GitHub Actions缓存key要带
--no-dev标志,例如:composer-${{ hashFiles('**/composer.lock') }}-${{ env.COMPOSER_FLAGS || '--no-dev' }},否则缓存复用导致dev包漏装或误装 - CI测试阶段用完整安装:
composer install && ./vendor/bin/phpunit;构建生产镜像那步,必须切回--no-dev - 别在运行时用
class_exists('PhpCsFixerFixer...')——它会触发autoload,--no-dev下直接崩。改用interface_exists()或加环境守卫:if (PHP_SAPI === 'cli') { ... }
最常被忽略的一点:require-dev的边界不是“我本地用不用”,而是“线上代码会不会加载它”。哪怕只有一行临时调试代码调用了dev包,上线就危险。

















