thinkphp6模型中密码加密需严格实现setpasswordattr方法:继承think\model、字段名password、使用password_hash()带cost=12及空值/长度校验,仅save()或create()触发,验证须用password_verify()。

ThinkPHP6模型中用修改器实现密码加密,核心是写对 setPasswordAttr 方法,并确保它真正被触发。这不是加个方法就完事,而是要卡准命名、继承、字段名、调用方式四个关键点。
必须严格匹配命名与继承规则
模型类必须继承 think\Model(不是 think\db\Model 或其他基类);数据库字段名是 password,方法名就必须是 setPasswordAttr——大小写敏感,不能写成 setpasswordattr、SetPasswordAttr 或 _setAttr。如果字段叫 pwd,就得写 setPwdAttr,否则逻辑完全不执行。
加密必须用 password_hash(),且带安全控制
别碰 md5、sha1、crypt 这些不安全或不可靠的方式。唯一推荐的是 PHP 原生的 password_hash():
- 算法选
PASSWORD_DEFAULT:随 PHP 升级自动演进,当前等价于 bcrypt,兼容 TP6 默认行为 - 显式指定
['cost' => 12]提升抗暴力能力,又不至于拖慢接口 - 开头判空:
if (empty($value)) return null;,避免password_hash(null)返回 false 导致入库失败 - 加长度校验:
if (strlen($value) > 72) throw new InvalidArgumentException('Password too long');,防超长输入和弱口令
绕过模型的操作不会触发修改器
这些写法完全跳过 setPasswordAttr:
$user->where('id', 1)->update(['password' => '123'])Db::name('user')->where('id', 1)->update(['password' => '123'])-
$user->password = '123'; $user->save();(直接赋值再 save,部分场景下也不触发)
真正生效的只有 $user->save()、UserModel::create() 这类走完整模型流程的操作。
查询时不能直接比对密文,得用 password_verify()
库里存的是哈希串(如 $2y$12$...),where('password', $input) 永远查不到结果。登录验证必须先查出用户记录,再用:
password_verify($input, $user->password)
注意:不能用 === 或 hash_equals() 对比两个哈希串,那是验证哈希是否一致,不是验证密码是否正确。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











