推荐静态调用模型,如User::find(1),需继承think\Model;助手函数model()适合复用实例;避免误用find()传条件、循环save()及混淆update()参数;Db操作不触发模型事件;可配置固定或动态数据库连接。

在 ThinkPHP 中调用模型,核心是确保模型类可被正确加载、继承规范、调用方式匹配其设计逻辑。最常用且推荐的方式是静态调用,它简洁、安全、自动触发模型初始化和事件机制。
模型类必须正确继承 think\Model
这是调用静态方法(如 User::find(1)、User::select())的前提。若报错 “Call to undefined method”,大概率是模型没继承基类:
- 模型文件(如 app/model/User.php)开头需包含:
namespace app\model;<br>use think\Model;<br><br>class User extends Model { } - 漏掉
use think\Model或未extends Model,静态查询方法就不存在 - 可选:显式指定表名(当不符合默认命名规则时),如
protected $name = 'user';
四种常用调用方式及适用场景
不同写法对应不同生命周期控制与复用需求:
-
静态调用(推荐):直接使用
User::find(1)、User::where('status', 1)->select()。不需实例化,自动走模型初始化、时间戳、验证、事件等完整流程 -
助手函数 model():如
$user = model('user');,返回已实例化的模型对象,适合需要多次操作同一模型实例的场景 -
Loader::model():如
$user = Loader::model('User');,本质是单例模式加载,兼容老项目,但 TP6 更倾向用model() -
new 实例后调用(慎用):如
$u = new User(); $u->where(...)->find();。容易绕过模型初始化逻辑,不推荐用于查询;仅在需手动控制属性或构造参数时考虑
常见误用与避坑要点
很多问题源于对方法签名和底层逻辑理解偏差:
立即学习“PHP免费学习笔记(深入)”;
-
find() 只接受主键值:写成
User::find(['username'=>'admin'])会静默返回 null;条件查单条请用User::where('username','admin')->find() -
批量操作别用循环 save():插入多条数据,用
User::saveAll([$data1, $data2]),而非反复new User()->save($d);前者支持事务、自动时间戳、字段过滤 -
update() 静态与实例方法参数含义不同:静态
User::update(['id'=>5,'name'=>'x'])自动识别主键;实例(new User())->update(['name'=>'x'])若无 where 条件,可能误更新全表 -
Db 类操作不触发模型事件:如用
Db::table('user')->where(...)->update(),before_update等回调完全不会执行
跨模块或动态数据库连接
业务复杂时需灵活切换数据源:
- 固定连接:在模型中定义
protected $connection = 'mysql_read';,所有操作都走该配置 - 临时切换:控制器中用
$logDb = Db::connect('mysql_log');获取独立 Query 对象,再执行$logDb->table(...)->select() - 租户级动态库:通过中间件解析租户标识,调用
Db::setConnectConfig()注册连接,并在模型基类中重写__callStatic自动注入->connect(tenant_x)



















