本文目录导读:

在ThinkPHP框架中,数据自动完成是一个非常实用的功能,它可以在数据写入数据库之前自动处理字段值,以下是详细的实现方法:
基本概念
数据自动完成包括:
- 自动填充:自动为字段设置默认值
- 自动转换:自动转换字段的数据类型
- 自动验证:自动验证数据的有效性(配合验证规则)
定义自动完成规则
在模型类中定义$auto属性:
<?php
namespace app\common\model;
use think\Model;
class User extends Model
{
// 自动完成规则
protected $auto = [];
protected $insert = [];
protected $update = [];
// 或者合并使用
protected $auto = [
'create_time',
'update_time',
'status' => 1,
'password' => 'md5',
'ip' => ['getClientIp', 1],
];
}
完整的自动完成示例
<?php
namespace app\common\model;
use think\Model;
class User extends Model
{
// 自动完成规则 - 所有操作
protected $auto = [
'create_time',
'update_time',
'status' => 1,
];
// 新增时自动完成
protected $insert = [
'password' => 'md5',
'register_ip' => ['getClientIp', 1],
'create_time' => 'time',
];
// 更新时自动完成
protected $update = [
'update_time' => 'time',
'last_login_time' => 'time',
];
// 自定义方法用于自动完成
protected function getClientIp()
{
return request()->ip();
}
protected function md5($value)
{
return md5($value . 'salt');
}
}
自动完成规则格式
自动完成规则支持多种格式:
// 1. 简单赋值
protected $auto = ['status' => 1];
// 2. 函数处理
protected $auto = ['password' => 'md5'];
// 3. 数组格式(方法名,参数类型)
protected $auto = [
'password' => ['md5', 1], // 1表示参数为整个数据
'create_time' => ['time', 2], // 2表示参数为当前字段值
'ip' => ['getClientIp', 3], // 3表示参数为默认值
];
// 4. 闭包函数
protected $auto = [
'order_no' => function($data) {
return 'ORD' . date('YmdHis') . rand(1000, 9999);
},
];
// 5. 使用think\facade\Hash
use think\facade\Hash;
protected $insert = [
'password' => function($data) {
return Hash::make($data['password']);
},
];
时间字段自动完成
<?php
namespace app\common\model;
use think\Model;
class Article extends Model
{
// 自动写入时间戳
protected $autoWriteTimestamp = 'datetime'; // 或 true 或 'int'
// 自定义时间字段名
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
// 自定义时间格式化
protected $dateFormat = 'Y-m-d H:i:s';
// 也可以使用自动完成
protected $insert = [
'create_time' => 'time',
'update_time' => 'time',
];
}
在控制器中使用
<?php
namespace app\index\controller;
use app\common\model\User;
class UserController
{
public function add()
{
$user = new User();
$data = [
'username' => '测试用户',
'email' => 'test@example.com',
'password' => '123456', // 密码会通过自动完成进行md5处理
];
// 自动完成会应用insert规则
$result = $user->save($data);
if ($result) {
return json(['code' => 1, 'msg' => '添加成功']);
} else {
return json(['code' => 0, 'msg' => '添加失败']);
}
}
public function edit($id)
{
$user = User::find($id);
$data = [
'email' => 'new@example.com',
'status' => 0,
];
// 自动完成会应用update规则
$result = $user->save($data);
return json(['code' => $result ? 1 : 0]);
}
}
与验证器配合使用
<?php
namespace app\common\validate;
use think\Validate;
class UserValidate extends Validate
{
protected $rule = [
'username' => 'require|max:25',
'email' => 'require|email',
'password' => 'require|min:6',
];
protected $message = [
'username.require' => '用户名不能为空',
'username.max' => '用户名最多25个字符',
'email.require' => '邮箱不能为空',
'email.email' => '邮箱格式错误',
'password.require' => '密码不能为空',
'password.min' => '密码最少6位',
];
}
// 在模型中使用
class User extends Model
{
protected $validate = 'app\common\validate\UserValidate';
protected $insert = [
'password' => 'md5',
'create_time' => 'time',
];
protected $update = [
'update_time' => 'time',
];
}
高级用法
<?php
namespace app\common\model;
use think\Model;
use think\facade\Request;
class Order extends Model
{
protected $auto = [];
protected $insert = [
'order_no' => ['createOrderNo', 1],
'status' => 1,
'create_time' => 'time',
'ip' => ['getClientIp', 1],
];
protected $update = [
'update_time' => 'time',
'handler' => ['getOperator', 1],
];
// 生成订单号
protected function createOrderNo($data)
{
return date('YmdHis') . rand(100000, 999999);
}
// 获取客户端IP
protected function getClientIp()
{
return Request::ip();
}
// 获取操作人
protected function getOperator()
{
return session('admin_id') ?: 0;
}
// 数据类型转换
protected $type = [
'price' => 'float',
'quantity' => 'integer',
'is_active' => 'boolean',
'meta' => 'json',
];
// 自动完成转换
protected $auto = [
'price' => ['floatval', 2],
'quantity' => ['intval', 2],
];
}
注意事项
- 执行顺序:自动完成在数据写入数据库之前执行
- 字段覆盖:自动完成会覆盖传入的相同字段值
- 性能考虑:复杂的自动完成逻辑会影响性能
- 优先级:
$insert和$update的优先级高于$auto - 调试技巧:可以使用模型的
getLastSql()方法查看最终执行的SQL
动态设置自动完成
// 动态修改自动完成规则 $user = new User(); $user->auto = ['custom_field' => 'custom_function']; $user->save($data); // 或者使用setter方法 $user = new User(); $user->setAuto(['username' => 'strtolower']); $user->save($data);
通过合理使用数据自动完成功能,可以大大减少代码重复,提高开发效率,并确保数据的一致性和安全性。