thinkphp模型定义关键在命名规范与配置匹配:类名user对应表user,文件路径app/model/user.php,命名空间严格遵循psr-4;表前缀统一在database.php配置,手动指定表名需设protected $table;命名错误或自动加载不匹配将导致查空或class not found。

模型定义不是“写个类就行”,关键在四个配置项是否匹配真实表结构——错一个,create() 会静默失败,find() 会查不到数据,时间字段可能报错。
模型生成命令要不要加 --migration?
加不加取决于你是否已存在对应数据表。如果表已建好(比如 legacy 系统),直接运行 php artisan make:model User 即可;如果要从零建表,才加 -m 或 --migration,它只生成空迁移文件,不会自动执行 migrate。
- 已有表:跳过迁移,专注模型配置
- 新项目且无表:加
-m,后续手动php artisan migrate - 别用
--model反向生成(Laravel 不支持)——没有工具能从表结构自动生成带正确$fillable的模型
$table 和 $primaryKey 为什么必须核对?
Eloquent 默认按类名推导表名(User → users),主键固定为 id。一旦实际表名是 my_users 或主键是 user_id,不显式声明就会出问题:
-
User::find(1)实际发 SQL:SELECT * FROM users WHERE id = 1→ 查不到(表不存在或字段名错) -
User::create([...])插入时忽略user_id字段,导致主键冲突或 NULL 错误 - 关联查询(如
$user->posts)会因表名/外键不匹配返回空集合
务必打开数据库确认真实表名和主键字段,然后在模型里写死:
protected $table = 'my_users'; protected $primaryKey = 'user_id';
$fillable 填错会导致什么?
$fillable 是白名单,不是可选配置——只要用 create()、update() 或批量赋值($user->fill([...])),就必须列全允许写入的字段。漏掉一个,那个字段就永远写不进数据库,且不报错。
- 常见错误:只写
'name'和'email',但表里还有'avatar_url',结果头像始终为空 - 安全风险:若误写成
$guarded = [](即黑名单为空),等于全放开,可能被注入is_admin字段 - 调试技巧:打印
$user->getAttributes()看哪些字段进了实例,再对比$fillable是否覆盖
$timestamps 设为 false 后还要注意什么?
设 public $timestamps = false; 确实能避免找不到 created_at 字段的报错,但它只是关掉自动维护,**不阻止你手动写入**:
- 如果你的表有
create_time字段,得自己在creating事件里赋值:$this->attributes['create_time'] = now()->format('Y-m-d H:i:s'); - 别混用:
$timestamps = false时还设const CREATED_AT = 'create_time'没意义,Eloquent 根本不读这个常量 - 时间字段类型要匹配:MySQL 的
DATETIME对应 PHPCarbon,TIMESTAMP可能有时区陷阱,本地开发和线上服务器时区不一致时尤其明显
最易被忽略的是:哪怕关了时间戳,save() 方法仍会尝试更新所有非主键字段,包括你没改过的 updated_at —— 如果该字段不允许 NULL 且没默认值,就会报错。











