ThinkPHP中控制器调用模型应遵循职责分离原则,推荐使用静态方法(如User::find(1))、new实例化或model()助手函数;须严格遵守命名与路径规范,避免D()函数、控制器写SQL及业务逻辑硬编码。

在ThinkPHP中,控制器调用模型的核心原则是:**明确职责分离,通过实例化或静态方式访问模型,完成数据操作,不直接耦合业务逻辑**。模型负责数据层交互,控制器只做请求分发和响应组装。
推荐的调用方式(TP6/TP5通用)
以下方式符合框架规范,且便于测试与维护:
-
使用模型类静态方法(最常用):
例如User::find(1)、User::where('status', 1)->select()。无需手动引入,框架自动加载,简洁高效。 -
new 实例化模型:
如$user = new User(); $user->name = '张三'; $user->save();。适合需要多次操作同一模型实例的场景(如批量赋值、链式设置)。 -
使用 model() 助手函数:
$user = model('User');返回单例对象,等价于new User(),写法更轻量。
注意命名与路径约定
模型类必须严格遵循命名与目录规则,否则调用会失败:
- 模型文件放在
app/model/或对应模块的model/目录下(如app/index/model/User.php); - 类名首字母大写、驼峰命名,对应数据表前缀去掉后的名称(如表
think_user→ 模型User); - 若表名特殊(如无前缀、含下划线),需在模型中显式定义
protected $table = 'my_user';。
避免错误用法
这些做法虽可能“跑通”,但违背设计原则,易引发隐患:
立即学习“PHP免费学习笔记(深入)”;
- 不要用
D('User')(ThinkPHP 3.x 遗留写法,TP5/6 已废弃); - 不要在控制器里写 SQL 查询(如
Db::table('user')->select()),除非是临时性、非业务核心的辅助查询; - 不要把数据处理逻辑(如字段计算、关联组装)硬编码在控制器中——应移到模型的方法里,例如
User::withProfile()->find(1)。
配合模型事件与验证提升健壮性
调用模型不只是增删改查,还要善用其内置能力:
- 在模型
init()中注册事件(如before_insert自动填充创建人); - 使用
validate(true)或验证规则注解,确保传入数据合规; - 对敏感操作(如删除)加软删除或日志记录,统一在模型层控制,而非控制器重复判断。



















