thinkphp-模型的自动时间戳和只读字段、数据类型和转换
模型自动时间戳
如果你想全局开启,在config/database.php 中,找到auto_timestamp设置为true;
// 自动写入时间戳字段
// true为自动识别类型 false关闭
// 字符串则明确指定时间字段类型 支持 int timestamp datetime date
'auto_timestamp' => true,
比如我tp_user表这么写的sql语句
CREATE TABLE `tp_user` (
`id` mediumint(8) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自动编号',
`username` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`password` char(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`create_time` datetime(0) NOT NULL DEFAULT '1997-01-01 01:01:01' COMMENT '创建时间',
`update_time` datetime(0) NOT NULL DEFAULT '1997-01-01 01:01:01' COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 302 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
其中create_time和update_time都设置了默认值
当我们开启全局自动写入时间戳的时候,当我们执行插入新数据时:
$user = new UserModel();
$user->username = '李白';
$user->password = '123';
$user->gender = '男';
$user->email = 'libai@163.com';
$user->price = 100;
$user->details = '123';
$user->uid = 1011;
$user->replace()->save();
数据表中的create_time和update_time字段就会自动更新为当天的时间。
当我给config/database.php中的auto_timestamp设置为false时,那么当我再次插入的时候,就不会自动更新为当天的时间了,而会采用其默认值1997。
如果你只想设置某一个模型开启,需要设置特有字段(当全局设置为false时)
在对应的模型文件User.php中
protected $autoWriteTimestamp = true;
这时,仅仅tp_user表执行操作时,会自动更新时间戳,而其他表则不受影响。
当然,还有一种方法,就是全局开启,单独关闭某个或某几个模型为false;(其实就是全局设置为false,个别模型中$autoWriteTimestamp设置为false)
自动时间戳开启后,会自动写入create_time 和update_time 两个字段;此时,它们的默认的类型是int,如果是时间类型,可以更改如下(datetime其实与默认的true没什么区别):
// config/database.php中
'auto_timestamp' => 'datetime',
// 或单独的模型文件中
protected $autoWriteTimestamp = 'datetime';
都配置完毕后,当我们新增一条数据时,无须新增create_time 会自动写入时间;同理,当我们修改一条数据时,无须修改update_time 会自动更新时间;
自动时间戳只能在模型下有效,数据库方法不可以使用。
如果创建和修改时间戳不是默认定义的,也可以自定义;
比如有如下表:
id | username | create_at | update_at |
---|---|---|---|
1 | wubin.work | 1987-***** | 2024-***** |
在模型文件中:
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
如果全局时间戳是true,而业务中只需要create_time 而不需要update_time,可以关闭它,在对应的模型中设置:
protected $updateTime = false;
关闭后,比如插入时会忽略update_time字段,而是采用其字段的默认值。
可以动态实现不修改update_time和create_time(当全局时间戳开启时)
在控制器,执行插入的操作时:
$user = new UserModel();
$user->username = '李白';
$user->password = '123';
$user->gender = '男';
$user->email = 'libai@163.com';
$user->price = 100;
$user->details = '123';
$user->uid = 1011;
$user->isAutoWriteTimestamp(false)->replace()->save();
链式添加isAutoWriteTimestamp(false)即可
模型只读字段
所谓的模型只读字段,指的就是新增之后,就不可以再修改的字段。
比如我们要设置username 和email 不允许被修改,如下:
控制器中,更新一条数据
// 首先找到一条
$user = UserModel::find(330);
// 然后执行修改
$user->username = '哈登';
$user->email = '111111@163.com';
$user->price = Db::raw('price + 1'); // 每次更新price自增1
$user->save();
然后在模型中设置只读字段为username和email,让这两个字段中的数据不随着更新而修改
// 只读字段 修改时无法修改(只可以新增)
protected $readonly = ['username', 'email'];
设置只读字段之后,就算更新数据不修改也不会报错。
除了在模型端设置,也可以动态设置只读字段(无需在模型中设置)
在控制器中:
// 首先找到一条
$user = UserModel::find(330);
// // 然后执行修改
$user->username = '杜兰特';
$user->email = '111111@163.com';
$user->price = Db::raw('price + 1');
$user->readonly(['username', 'email'])->save();
只读字段只支持模型方式不支持数据库方式
模型的数据类型和转换
普通是将结果直接进行类型转换,比如:
$user = UserModel::find(20);
var_dump((boolean)$user->status);
var_dump((float)$user->price);
integer(整型)、float(浮点型)、boolean(布尔型)、array(数组)object(对象)、serialize(序列化)、json(json)、timestamp(时间戳)datetime(日期)
一般datetime都是字符串类型。
如果要模型自动在取值的时候就要对相应的字段完成数据类型的转换,需要在模型中进行设定:
// 类型转换
protected $type = [
'status' => 'boolean',
'price' => 'float',
'create_time' => 'datetime:Y-m-d'
];
其中还可以对时间进行格式化处理。
废弃字段,当某个字段在开发项目版本升级中不再使用,可以设置为废弃字段,废弃字段,当某个字段在开发项目版本升级中不再使用,可以设置为废弃字段。查询就不会被查询到。
在模型中:
//设置废弃字段
protected $disuse = ['status', 'uid'];
设置后,在控制器中查询等,就会忽略这些字段,不显示其值。