因为composer的psr-4规则默认不区分环境,只要autoload中配置了"tests": "tests/"就会加载测试类;根治方案是将其移至autoload-dev并配合composer install --no-dev --optimize-autoloader --classmap-authoritative部署,确保autoload_psr4.php中无tests键且class_exists('testsexampletest')返回false。

为什么composer dump-autoload总把Tests类加载进生产环境
因为 Composer 的 PSR-4 规则不区分开发与生产——只要 composer.json 的 autoload 里写了 "Tests\": "tests/",它就会扫描 tests/ 下所有 PHP 文件并注册进 vendor/autoload.php。这不是 bug,是默认行为。后果很实在:生产环境多加载几十个测试类,内存占用涨、冷启动慢、还可能触发测试类里的静态初始化逻辑(比如 mock 全局状态)。
正确做法:把测试映射从 autoload 搬到 autoload-dev
这才是根治方案,不是打补丁。Composer 原生支持开发专用自动加载,且 --no-dev 会彻底忽略它。
- 删掉
autoload段里所有测试相关映射,例如:"Tests\": "tests/" - 在
autoload-dev下补上同样配置:"autoload-dev": {"psr-4": {"Tests\": "tests/"}} - 确保 CI 或本地开发时运行的是
composer install(默认含--dev),而生产部署必须用:composer install --no-dev --optimize-autoloader --classmap-authoritative --prefer-dist --no-interaction - 验证:部署后检查
vendor/composer/autoload_psr4.php,确认"Tests\"键不存在;再运行php -r "var_dump(class_exists('Tests\ExampleTest'));",应返回false
exclude-from-classmap 是备选,但容易失效
如果你暂时无法调整 autoload 结构(比如继承的旧项目),可用 exclude-from-classmap 挡一下,但它有硬限制:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 只对 PSR 和 classmap 生效,对
files类型无效 - 路径必须以
/结尾,如:"tests/", "Tests/", "fixtures/" - 如果
autoload里还保留着"Tests\": "tests/"这种 PSR 映射,exclude-from-classmap完全不生效——PSR 规则优先级更高 - 执行
composer dump-autoload -o后,务必打开vendor/composer/autoload_classmap.php搜索Test,确认无残留
部署后必须验证三件事,缺一不可
很多团队以为加了 --no-dev 就万事大吉,结果线上仍加载测试类。真正生效要看这三点:
-
vendor/composer/autoload_psr4.php里没有Tests\或其他测试命名空间条目 -
vendor/autoload.php中'classmap-authoritative' => true存在且为true(说明 fallback 已关) - 运行
php -d display_errors=1 -r "new TestsFooTest();"应直接报Class 'TestsFooTest' not found,而不是静默失败或意外初始化
最常被忽略的是第三点:不实际触发类加载,就永远不知道 autoloader 是否真甩掉了测试代码。










