前提介绍
TP版本:3.2.3
涉及到的方法:数据更新中的 setInc 和 setDec
应用场景:对于统计字段(通常指数字类型)的更新
实际场景:对于点赞次数的增加
表结构
CREATE TABLE `question` (
`id` int(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
`uid` int(20) unsigned NOT NULL COMMENT '用户ID',
`content` VARCHAR (200) NOT NULL DEFAULT '' COMMENT '问题内容',
`answer` VARCHAR (200) NOT NULL DEFAULT '' COMMENT '回答内容',
`like` int(20) unsigned NOT NULL DEFAULT 0 COMMENT '点赞',
`unlike` int(20) unsigned NOT NULL DEFAULT 0 COMMENT '踩',
`status` tinyint(4) NOT NULL DEFAULT 1 COMMENT '提问状态:1-提问;2-回答;3-发布;0-屏蔽',
`remark` VARCHAR (300) NOT NULL DEFAULT '' COMMENT '备注',
`reg_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE INDEX `id` ( id ASC),
INDEX `uid` (`uid`)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
注:这张表中存在一个问题,也是令我写下这篇文章的起因所在,下文会有说明
方法
public function edit_(array $data = null)
{
if (!$this->field('id,type')->create($data, self::MODEL_UPDATE))
throw new \XYException(__METHOD__, $this->getError());
unset($this->type);
$fields = '';
if ($data['type'] == 1)
$fields = "like";
elseif ($data['type'] == 0)
$fields = "unlike";
// 由于上面调用了create(),这里不必写更新条件,原因请看下面注释(1);字段值默认增加 1。
$res = $this->setInc($fields);
if ($res === false || $res === null)
throw new \XYException(__METHOD__, -8000);
if ($res > 0)
return 1;
return 0;
}
这里直接运行,会抛出SQL语句错误异常。
异常语句为:
UPDATE `question` SET `like`=like+1 WHERE `id` = 1
异常原因是:
表字段与MySQL的关键字冲突,MySQL会将'like'字段,当作like关键字处理。
解决思路:
通过 `` 反引号转义 ,表示为此为表中的字段
实施
加条语句,修改下变量名即可

注:setDec 方法的修改同上。
注释
(1)两个原因:
1、由于TP框架在Model.class.php文件中,设置了默认主键名称为"id"


2、$this->field('')->create()的意思是:根据表单提交的POST数据和通过field字段筛选后创建数据对象,这时"id"已存入内存中,之后也是通过 save 方法,将数据读取出来。

仔细观看,可发现原因1的图片中存在
if (is_string($pk) && isset($data[$pk]))
这里调用的 $data[''] 就是上图中的$data。
网友评论