PSR-4 是默认且最常用模式,要求命名空间结尾必须带反斜杠(如 "App\": "src/"),路径与命名空间严格对齐,不解析下划线为目录,开发期友好但性能依赖 OPcache;classmap 通过预生成类路径映射提升加载速度,需显式配置并启用 --classmap-authoritative 才彻底跳过文件扫描;files 模式仅用于一次性加载函数/常量文件,不参与类自动加载;autoload-dev 与 autoload 叠加生效,部署时须用 --no-dev 隔离测试代码;所有配置修改后必须执行 composer dump-autoload 并确认终端输出成功提示,同时清理 IDE 缓存以防旧映射残留。

psr-4 是默认且最常用的模式,但必须写对命名空间结尾
psr-4 不是“能用就行”,错一个字符就直接报 Class not found,而且错误不提示哪行配错了。最常见的是漏掉反斜杠:"App": "src/" ❌ 会触发 [InvalidArgumentException] A non-empty PSR-4 prefix must end with a namespace separator;正确写法是 "App\": "src/" ✅(JSON 中双反斜杠,解析后为单反斜杠)。
它要求文件路径和命名空间严格对齐:比如 App\Http\Controllers\HomeController 必须落在 src/Http/Controllers/HomeController.php。如果你的类名含下划线(如 My_Class_Name),psr-4 会找 My_Class_Name.php,不会拆成目录——这点和已淘汰的 psr-0 完全不同。
- 适合新项目、有清晰命名空间结构的代码
- 开发期友好:增删类文件无需重跑
dump-autoload(只要目录结构没变) - 性能上每次 new 类都要拼路径 +
file_exists(),OPcache 缓存不了这部分逻辑
classmap 能显著提速,但只对静态类有效
classmap 不是“开了就快”,它是把指定目录下所有 .php 文件扫描一遍,生成一张「类名 → 绝对路径」的静态数组,存在 vendor/autoload_classmap.php 里。加载时直接查表,跳过所有磁盘查找。
验证是否生效:看 vendor/autoload_classmap.php 是否非空;或运行 composer dump-autoload -v,输出里出现 generating optimized autoload files (using classmap) 才算真启用了。
- 必须显式配置
"classmap": ["src/", "legacy/"],空数组都不触发 - 启用
--classmap-authoritative后,Autoloader 完全跳过文件系统扫描——漏掉的类会直接 fatal error,不是 warning - 动态生成的类(
eval()、条件include)、测试类、trait 文件,进不了 classmap
files 模式只加载函数/常量,千万别塞类文件
"files" 字段干一件事:在 vendor/autoload.php 被 require 的瞬间,把列表里的 PHP 文件全部 require_once 一次。它不参与类查找,也不支持按需加载。
典型用途是引入全局辅助函数或常量定义,比如 "files": ["src/functions.php", "src/constants.php"]。如果误把 Foo.php(里面定义了 class Foo)放进去,new Foo() 依然会失败——因为 files 不注册类映射。
- 重复包含无副作用,但每次请求都执行,大项目里多几个就会拖慢启动
- 路径是相对于
composer.json的,不是当前工作目录 - 它和 psr-4/classmap 共存,但完全不互相影响
autoload-dev 和 autoload 不是开关关系,而是叠加关系
很多人以为 autoload-dev 只在 composer install --dev 时生效,其实只要没加 --no-dev,它的规则就一直被合并进 autoloader。比如你配了 "Tests\": "tests/",那么 new Tests\TestCase 在本地开发和 CI 环境都能跑通。
真正要隔离的是上线环境:部署时必须加 composer install --no-dev,否则 vendor/autoload.php 里会混入测试类路径,既增大体积又可能引发安全或冲突问题。
-
composer dump-autoload --no-dev会清掉autoload-dev生成的映射,这点容易被忽略 - 改完
autoload-dev后不跑dump-autoload,测试类照样找不到 - IDE 或 PHPUnit 可能缓存旧 autoloader,删掉
vendor/composer/autoload_*.php再重生成最稳妥
真正卡住人的往往不是选哪种模式,而是改了 composer.json 没跑 dump-autoload,或者跑了但没注意终端输出是否显示 Generated autoload files;更隐蔽的是 IDE 缓存了旧的 autoload_*.php,看着配置对了,实际加载的还是旧映射。











