autoload必须是composer.json顶层字段,与name、require同级;正确写法如"autoload": {"psr-4": {"app\": "src/"}},需确保命名空间以双反斜杠结尾、路径为相对正斜杠结尾、大小写严格一致,并执行composer dump-autoload生效。

composer.json里autoload配置写在哪、怎么写才生效
autoload必须是composer.json的顶层字段,和name、require平级,不能塞进extra、scripts或require里——写错位置,Composer直接忽略,不报错也不提示。
正确写法示例:
"autoload": {
"psr-4": {
"App\": "src/"
}
}
关键点:
-
"App\"必须是双反斜杠:JSON里表示一个字面量反斜杠,PHP解析后是"App";写成"App"或"App/"都匹配失败 -
"src/"是相对路径,以正斜杠结尾;写成"src"会导致拼出srcMyClass.php,写成"/src/"或"../src/"会被Composer拒绝 - 路径必须真实存在,且大小写完全一致:
src/≠Src/(Linux/macOS下)
命名空间、目录结构、类名三者怎么对齐
PSR-4不做扫描,只做字符串替换:剥离命名空间前缀后,把剩余部分的全换成/,再拼上配置路径,最后加.php。
比如new AppHttpControllersHomeController():
- 剥离
App\后剩HttpControllersHomeController - 转
/得Http/Controllers/HomeController - 拼路径
src/→src/Http/Controllers/HomeController.php
所以必须同时满足:
- 文件真实存在于
src/Http/Controllers/HomeController.php(注意大小写) - 该文件里声明
namespace AppHttpControllers;(开头无空格,结尾有分号) - 该文件里定义
class HomeController(名字完全一致,不能是homecontroller或Controller)
为什么改了配置还是Class not found
因为vendor/autoload.php只是启动器,真正干活的是vendor/composer/autoload_psr4.php——它不会监听文件变化,只在composer dump-autoload时重写。
常见静默失效场景:
- 改完
composer.json没运行composer dump-autoload,映射根本没进autoload_psr4.php - 运行了
dump-autoload但src/目录不存在,命令不报错,运行时才炸 - 代码里先
new AppHttpControllersHomeController()再require 'vendor/autoload.php', autoload队列还没注册就触发了加载 - 手动写了
spl_autoload_register()或__autoload并返回false,拦截了Composer的加载器
调试建议:直接var_dump(include 'vendor/composer/autoload_psr4.php');看数组里有没有你配的键值对。
vendor/autoload.php为什么必须放在入口第一行
它不定义类,只执行注册动作:调用ClassLoader::getLoader(),内部用spl_autoload_register()把PSR-4逻辑挂进PHP自动加载队列。
如果这行被放到new语句后面,PHP实例化时已触发autoload机制,但队列为空,直接抛Class not found——不是报错,是根本没处理。
务必确认:
-
public/index.php(或其他入口)顶部第一行就是require __DIR__.'/../vendor/autoload.php'; - 没被
require_once覆盖、没被条件判断包裹、没被其他autoload.php替代 - 没在框架启动前调用
set_include_path()或自定义__autoload
最麻烦的其实是“看起来能跑”:某些类可能被依赖提前加载过,掩盖了autoload未注册的问题,一换环境就崩。











