ThinkPHP模型中字段类型转换需显式配置$types数组,如'id'=>'integer',且仅对数据库查询结果生效;请求参数需单独用filter处理,类型配置错误会导致静默降级。

ThinkPHP 模型里写 'id' => 'integer' 才能触发字段自动转整型,写 'int' 或 'intger' 都无效 —— 这是多数人第一次配错就卡住的地方。
Model 的 $type 数组必须手动定义且键值严格匹配
ThinkPHP 不会读数据库字段类型(比如 MySQL 的 INT),也不会根据 PHP 原生类型名推断。你必须在模型类里显式声明:protected $type = ['id' => 'integer'];
-
$type必须是protected,写成public或不加修饰符,整个数组会被忽略 - 键名是字段名本身,不能带表前缀,也不能用 SQL 别名(如
user_id AS uid里的uid不生效) - 值只能是 ThinkPHP 内置识别的字符串标识:
'integer'(不是'int')、'boolean'、'datetime'、'timestamp'等 - MySQL 的
TINYINT(1)不会自动当布尔处理,得写'status' => 'boolean'
integer 和 timestamp 对时间字段的行为完全不同
如果你把一个存字符串时间(如 '2024-05-30 10:12:33')的字段配成 'create_time' => 'timestamp',它会尝试解析成秒级整数;失败就返回 0,而不是抛错或留原字符串。
-
'create_time' => 'datetime'→ 返回 Carbon 实例,可调->format()、->diffForHumans() -
'create_time' => 'timestamp'→ 强制转为int,比如1717023456,适合做数值计算或传给 JSDate() - 两者都不容错:配错类型 + 数据格式不匹配 = 静默降级(如空串、非法格式都变
0或null)
请求参数里的 id 是字符串?别指望 $type 自动管
模型的 $type 只影响从数据库查出来的数据,对 HTTP 请求参数($this->request->param('id'))完全不起作用。哪怕你模型里写了 'id' => 'integer',param('id') 返回的仍是字符串。
- 想让请求参数转整型,得用
filter参数:$this->request->param('id', 0, 'intval') - 验证规则(如
'id|require|integer')只校验,不转换;validate()通过后拿到的还是原始字符串 - 如果后续要进数据库写入,又用了模型赋值(如
$model->id = $this->request->param('id')),那这时才触发模型的$type转换 —— 但前提是这个值已经进了模型属性,不是直接塞 SQL
最容易被忽略的是边界情况:数据库字段是 INT UNSIGNED,但 PHP 整型溢出时不会报错,2147483648 在 32 位系统上会变成负数;而 $type = ['id' => 'integer'] 不做范围检查,也不兼容大整数字符串(如雪花 ID)。真要处理超大数字,得绕过自动转换,手动用 filter_var($id, FILTER_VALIDATE_INT) 或保留为字符串。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











