autoload-dev 中 classmap 与 psr-4 混用会失效,因 psr-4 优先匹配且不 fallback;须单选其一并确保路径/命名空间严格一致,修改后需执行 composer dump-autoload --dev 生效。

autoload-dev 里 classmap 和 psr-4 混用会失效
很多人把测试类路径同时写进 classmap 和 psr-4,结果 phpunit 找不到测试类——Composer 的 autoload-dev 加载规则是“先匹配到谁就用谁”,psr-4 优先级高于 classmap,但若命名空间不严格对应目录结构,psr-4 匹配失败后也不会 fallback 到 classmap。
正确做法是只选一种,且确保路径与命名空间一致:
- 用
psr-4:测试类必须在tests/下,且命名空间以Tests\开头(如Tests\Unit\ExampleTest对应tests/Unit/ExampleTest.php) - 用
classmap:适合老项目或非标准结构,直接指向含测试类的目录,无需命名空间约束,但每次增删文件后要手动执行composer dump-autoload --dev
修改 composer.json 后必须重新生成 autoloader
改完 autoload-dev 不运行命令,新配置完全不生效。Composer 不会在每次 require 时动态解析 composer.json。
关键命令只有两个:
-
composer dump-autoload --dev:仅重新生成开发依赖的自动加载映射(推荐日常使用) -
composer install --no-autoloader && composer dump-autoload --dev:适用于 CI 环境或怀疑主 autoloader 被污染时
验证是否生效:查看 vendor/composer/autoload_dev.php 文件末尾,确认你的路径或命名空间映射已写入数组中。
PHPUnit 启动时报 Class not found?检查 vendor/autoload.php 是否被正确引入
很多测试脚本(尤其是自定义启动逻辑)直接 require 'vendor/autoload.php',但这只加载 autoload(生产代码),不包含 autoload-dev。结果就是测试类明明配了,却报 Class 'Tests\Unit\ExampleTest' not found。
解决方案分场景:
- 用
phpunit.xml配置:确保存在 —— 这个autoload.php是 Composer 生成的完整入口,已合并 dev 配置 - 命令行直接跑:用
php -d auto_prepend_file=vendor/autoload.php vendor/bin/phpunit tests/,避免手写 require - 写测试引导文件:必须
require __DIR__.'/vendor/autoload.php';,不能只 require 生产 autoload 文件
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
}
}
测试类文件位置和命名空间必须严格对应:tests/Unit/ExampleTest.php 内必须声明 namespace Tests\Unit;。少一个反斜杠、多一个空格,psr-4 就不会加载它。
最容易被忽略的是:CI 环境下 composer install 默认跳过 autoload-dev,除非明确加 --dev 或设置 COMPOSER_DEV_MODE=1。没这一步,整个 autoload-dev 配置形同虚设。










