thinkphp 6.x已彻底移除$_auto,自动完成须改用$insert/$update数组、setxxxattr修改器或before_write钩子;字段白名单需配合allowfield(true)使用,排序参数必须通过静态白名单校验后以数组形式传入order()。

刚接触ThinkPHP的新手常以为配置好$_auto数组就能让字段自动写入,结果发现create_time始终为NULL、status没默认值、密码也没加密——这是因为TP5.1+已废弃$_auto,TP6.x彻底移除,旧文档配置直接失效。
确认你的ThinkPHP版本和对应机制
执行php think version查看当前版本:若输出v6.x,则$_auto、$auto、$filter等全部无效;若为v5.0.x,仍可有限使用但已标记废弃;v5.1+起所有自动完成逻辑必须迁移到$insert/$update数组或修改器。
这一步跳过将导致后续所有配置白费力气,且不会报错,只会静默失败。
TP6中替代$_auto的三种安全写法
方法一:用$insert和$update数组控制字段写入时机
在模型类中定义:
【protected $insert = ['create_time', 'status', 'password'];
【protected $update = ['update_time'];
注意:字段名必须与数据库列名完全一致(如create_time不能写成createTime),且仅对save()、create()生效;Db::table()->insert()等直连查询完全绕过此机制。
方法二:用setXxxAttr修改器做字段级处理
例如对password字段自动MD5:
public function setPasswordAttr($value)
{ return md5($value); }
该方法仅在模型赋值时触发(如$user->password = '123'),不依赖表单提交方式,也不受白名单过滤影响。
方法三:用beforeWrite钩子统一注入业务逻辑
在模型init()中注册:
self::event('before_write', function ($model) {
if (empty($model->data['create_time'])) {
$model->data['create_time'] = date('Y-m-d H:i:s');
}
if (!empty($model->data['status'])) {
$model->data['update_time'] = date('Y-m-d H:i:s');
}
});
⚠️关键点:必须操作$model->data数组,而非$model属性;且不能在钩子里修改主键或关联字段,否则save()可能出错。
字段白名单设置防越权写入
第一步:在模型中声明允许写入的字段列表
【protected $field = ['id', 'name', 'email', 'status', 'create_time', 'update_time'];
第二步:调用save()前显式启用白名单校验
$user = new User();
$user->allowField(true)->save($data);
第三步:若需动态控制,可在控制器中构造安全字段集
$safeData = [];
foreach ($data as $k => $v) {
if (in_array($k, User::$fillable)) { // 假设模型已定义static $fillable
$safeData[$k] = $v;
}
}
$user->save($safeData);
不设$field或不调用allowField(true),模型会丢弃所有未声明字段,哪怕你在$data里写了status=0也进不了数据库。
排序字段白名单防SQL注入
用户传参的sort字段绝不能直接拼进order():
错误写法:$list = User::order(input('sort') . ' ' . input('order'))->select();
正确路径:控制器→模型静态白名单→安全提取→数组order
① 在User模型中定义:【protected static $sortableFields = ['name', 'email', 'create_time', 'status'];
② 控制器中提取并校验:
$sort = input('sort/s', 'id');
$order = strtolower(input('order/s', 'asc'));
if (!in_array($sort, User::$sortableFields) || !in_array($order, ['asc', 'desc'])) {
throw new HttpException(400, '非法排序参数');
}
③ 执行查询:
$list = User::order([$sort => $order])->select();
数组写法order(['name'=>'asc'])强制走PDO参数绑定,字段名虽仍需白名单校验,但值已被安全转义,杜绝注入可能。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











