ThinkPHP 6+ 模型类需严格满足PSR-4规范:命名空间、文件路径、类名三者完全对应,且必须在composer.json中显式配置"appmodel": "app/model/"等映射并执行composer dump-autoload,否则即使文件存在也报Class not found。

ThinkPHP 6+ 的模型类不会自动加载,除非它满足 PSR-4 命名空间与路径的严格对应关系,且已注册进 Composer 的 autoload 配置;否则即使文件存在、命名正确,也会报 Class "appmodelUser" not found。
模型类文件放对位置但还是找不到?检查命名空间和文件名大小写
ThinkPHP 不会“扫描目录”找类,它靠命名空间字符串推导路径。比如你要用 appmodelUser,自动加载器会尝试加载 app/model/User.php —— 注意三个关键点:
- 文件路径必须是
app/model/User.php(不是app/model/user.php或app/model/UserModel.php) - 类定义顶部的命名空间必须是
namespace appmodel;(不能是Appmodel、appModel或漏掉app) - 类名必须与文件名完全一致:
class User对应User.php,class UserModel就得叫UserModel.php
composer.json 没配 appmodel 的 PSR-4 映射
ThinkPHP 6 默认不把 app/ 目录纳入 Composer 自动加载,所以哪怕你写了 appmodelUser,Composer 也根本不知道去哪找。必须手动加映射:
- 编辑项目根目录的
composer.json,在"autoload": {"psr-4": {...}}里加一行:"app\model\": "app/model/" - 注意双反斜杠:
\是 JSON 字符串里转义反斜杠的写法,不能写成"appmodel"或"app/model/" - 执行
composer dump-autoload(开发阶段不用加-o,加了反而可能绕过 PSR-4 走 classmap,导致改了类名也不生效)
用了 use appmodelUser 却在中间件或服务提供者里提前触发加载
PSR-4 是按需加载,但 use 语句本身不触发加载,真正触发的是第一次 new、static:: 调用或类型提示(如函数参数声明 User $user)。容易踩坑的地方:
立即学习“PHP免费学习笔记(深入)”;
- 在
app/common.php或全局中间件里写了new appmodelUser()→ 应用一启动就加载,失败直接崩 - 在控制器方法里用
Db::name('user')是 OK 的,它不依赖模型类,但换成User::find(1)就必须确保User类能被自动加载 - 依赖注入容器里绑定
User::class也会提前触发加载,若此时 autoload 还没配好,就会报错
extend/ 或自定义目录下的模型类怎么加载?
ThinkPHP 不会自动扫描 extend/,哪怕你把模型放进去,不配 autoload 就等于不存在。解决方式只有一种:
- 在
composer.json的psr-4里加映射,例如:"extend\user\model\": "extend/user/model/" - 路径末尾带斜杠,命名空间末尾带双反斜杠,两者必须对齐
- 别用
Loader::addNamespace()—— TP6 已弃用,且它只影响 ThinkPHP 自己的 Loader,不影响 Composer 加载链,第三方包或new实例化时照样失败
最常被忽略的一点:改完 composer.json 后没运行 composer dump-autoload,或者误以为清空 runtime/ 就能重置自动加载——其实那只是缓存模板或配置,跟类路径映射毫无关系。



















