autoload-dev 应配置开发专用路径如 tests/、scripts/,用 psr-4(如 “tests”: “tests/”)或 classmap 映射,不可含业务代码或上级目录;其加载依赖 vendor/autoload-dev.php,仅在 –dev 模式下生成并生效。

autoload-dev 里该写什么路径
它只管开发时用的代码,比如测试类、命令行工具、Mock 类——这些不该进生产包。composer 不会把 autoload-dev 里的内容打包进 vendor/autoload.php 的主加载逻辑里,而是单独挂到 dev 模式下。
常见错误是把业务代码误塞进去,结果跑测试时正常,一上线就 Class not found;或者反过来,把 PHPUnit 的 tests/ 放进主 autoload,污染生产环境。
-
psr-4最常用:比如"Tests": "tests/",注意命名空间末尾的反斜杠和路径结尾的斜杠都要有 -
classmap适合零散文件:比如"scripts/dev-helper.php"这种无命名空间的工具脚本 - 别写相对路径以外的路径(如
../shared-tests),Composer 不会解析上级目录,会静默忽略
为什么 vendor/autoload.php 不自动包含 autoload-dev
因为 Composer 的自动加载器分两层:主加载器(vendor/autoload.php)只加载 autoload 配置;dev 加载器是额外生成的,叫 vendor/autoload-dev.php,只在 composer install --dev 或默认安装时存在。
你运行 phpunit 或 php artisan test 时,框架或工具通常会显式 require 它;但如果你手写脚本直接 include vendor/autoload.php,那 autoload-dev 里的类就根本不会注册。
- 检查是否真有
vendor/autoload-dev.php:它不是 always 存在,删掉vendor后只执行composer install --no-dev就没有 - phpstorm 或其他 ide 默认不识别
autoload-dev,需要手动在设置里添加vendor/autoload-dev.php到 include path - 某些 CI 环境(如 github Actions)默认走
--no-dev,记得加--dev或删掉该 flag
autoload 和 autoload-dev 冲突了怎么办
不会真正“冲突”,但行为容易迷惑:比如你在 autoload 里写了 "App": "src/",又在 autoload-dev 里写了 "AppTests": "tests/",Composer 允许——只要命名空间不重叠。但若两者都映射到同一命名空间(比如都写 "App": "src/" 和 "App": "tests/app/"),后加载的会覆盖前一个,而 autoload-dev 是后加载的。
- 命名空间必须严格区分:生产代码用
App,测试代码用Tests或AppTests,别混用 - 如果非要用同命名空间(比如为本地 Mock 替换类),得靠
files+ 条件判断,而不是依赖自动加载顺序 - 用
composer dump-autoload -o生成优化后文件时,autoload-dev也会被合并进vendor/composer/autoload_classmap.php,但仅当--dev开启时才生效
怎么验证 autoload-dev 是否生效
最直接的办法不是看文件存不存在,而是看类能不能 new 出来,且不报错——但要注意触发时机。
- 运行
composer dump-autoload --dev后,检查vendor/composer/autoload_psr4.php里是否有你配的Tests条目 - 在 CLI 脚本里临时加一行:
var_dump(class_exists('TestsExampleTest'));,然后php script.php—— 如果是 false,大概率没加载autoload-dev.php - 别依赖 IDE 的自动补全来判断:它可能缓存了旧映射,重启索引或删掉
vendor/composer/autoload_*.php再试
最常被忽略的是:你以为自己在 dev 环境,其实当前 Composer 命令用了 --no-dev,或者项目根目录下有 COMPOSER_NO_DEV=1 环境变量。这种时候,autoload-dev 彻底失能,连文件都不会生成。