Composer autoload 不支持直接排除文件夹,仅支持显式包含;psr-4 会扫描整个前缀路径下所有 PHP 文件,无法忽略特定子目录;classmap 是唯一可控方式,需手动列出要加载的目录,新增类后须重运行 dump-autoload。

composer.json 的 autoload 里不能直接排除文件夹
Composer 的自动加载机制(autoload)只支持「显式包含」,不提供 exclude 或 ignore 这类配置项。你无法在 psr-4 或 classmap 下写 “除了 tests/ 都扫” 这种逻辑。常见错误是试图在 psr-4 映射中留空或用 ! 语法,结果 composer dump-autoload 直接报错或静默忽略。
classmap 是唯一能间接“排除”的方式
如果你的项目结构混杂(比如 src/ 下有要加载的类,也有 src/Examples/ 或 src/Scripts/ 这类非类文件),psr-4 会把整个命名空间前缀下的所有 PHP 文件都纳入扫描——它不区分用途。这时改用 classmap 更可控:
{
"autoload": {
"classmap": [
"src/Service/",
"src/Model/",
"src/Exception/"
]
}
}
这样只有明确列出的目录会被扫描生成映射表,其他子目录(如 src/Examples/、src/Utils/DebugHelper.php)完全不会进入 autoload。注意:classmap 不依赖命名空间,只按文件路径找 class、interface、trait 声明。
- 运行
composer dump-autoload -o后,生成的vendor/composer/autoload_classmap.php里只含你指定路径下的有效类 - 如果某目录下有大量非类 PHP 文件(如配置脚本、CLI 入口),
classmap能避免它们被误解析导致的解析错误 - 缺点:新增类文件后必须手动重跑
composer dump-autoload,不像psr-4那样支持开发时动态发现
真正需要排除的其实是 Composer 的依赖分析和安装阶段
很多人实际想屏蔽的是:不让 Composer 在 composer install 时处理某些目录(比如 node_modules/、.github/、docs/),避免扫描耗时或触发意外的 autoloader 生成。这跟自动加载无关,而是通过 composer.json 的 archive 或构建工具控制:
-
"archive": {"exclude": ["/node_modules/", "/.git/", "/docs/"]}—— 仅影响composer archive打包行为,不影响本地install - 更通用的做法:在项目根目录加
.gitattributes,用export-ignore标记(Git 归档时跳过),Composer 的install默认走 Git clone 或 zip 下载,会尊重这个规则 - CI 场景下,直接在
composer install前用rm -rf node_modules docs更干脆——Composer 本身不扫描这些目录,除非你把它写进了autoload或scripts
别让 autoload-dev 和生产环境混淆
最容易被忽略的一点:你可能以为把测试代码放进 tests/ 并配到 autoload-dev 就算“排除”了,但其实只要执行了 composer install --no-dev,这部分映射根本不会写入最终的 autoload 文件——它压根不存在于生产环境。关键在于:
-
autoload-dev中的路径(如"psr-4": {"Tests\": "tests/"})只在--dev模式下生效 - 如果误把
tests/写进了主autoload,那它就真的会被加载,且无法“排除” - 检查是否误配:运行
composer show -p,看autoload和autoload-dev分区是否清晰;再查vendor/composer/autoload_psr4.php里有没有不该出现的键
真正难处理的是历史遗留项目里混在 src/ 下的脚本或模板文件——它们既不是类,又不能挪走。这时候老老实实用 classmap 列出确定要加载的子目录,比硬塞一堆排除规则更可靠。











