ThinkPHP数据自动验证中unique的缺陷

2010-6-23

ThinkPHP可以为Model添加$_validate属性,使得在使用create方法创建数据对象时能自动对数据进行验证,详细看这里

这其中有个unique的方法,即是验证指定栏的数据在表中是否唯一。向数据表里插入“唯一”字段时可以自动判断并且提示错误,但ThinkPHP这个功能有个缺陷,导致这个unique验证基本上只能在添加数据的时候使用,不能在编辑数据的时候用。

unique验证的源码在ThinkPHP/Lib/Think/Core/model.class.php第944行,对unique验证时就是查找整个数据表这一栏这个值是否存在,这样做在添加数据时没问题,但如果在编辑状态下就有问题了。例如编辑一个用户名和密码,现在不修改用户名只修改密码,因为用户名要进行唯一验证,此时这个用户名没有修改,数据表上是有这个用户名的(就是在编辑的这行数据),于是就提示已存在此数据,无法保存。

我想解决的办法可以是:在验证的时候判断是否传进了此表主键的值,例如判断是否传进了$_POST[“admin_id”],如果传进了,对搜索到的数据提取admin_id判断是否相等,相等则不存在unique错误,不相等才出现错误。在这么核心的地方调用$_POST似乎破坏结构,那可以改改$_validate传递的参数。还不熟悉ThinkPHP,就不动手改了。

目前在我的应用中是只在新增数据时检测unique,编辑时不检测,如果编辑时unique的栏有重复了,再在save()时判断是否插入成功和提示,暂时是这样。

分类:技术文章 Tags:
评论

2010年6月29日 19:13

笨笨深夜造访,前来问候。

2013年4月28日 22:19

非常同意,看过之后,我想到一个方法,就是在input标签中,把name属性值该了(比如原来是admin_id,则可改为aid),这样后台验证时就捕捉不到了,然后通过$_POST[aid]获取,再存入$data[‘admin_id’]中,最后sava($data).

2013年4月28日 22:24

不行,如果对于同一字段还有其他验证,那就不能进行验证了,呵呵。。。白白的。。。。

2013年4月28日 22:42

在代码中动态改变验证规则:$validate=array(验证规则); $modelname->setProperty(‘_validate’,$validate);

2013年5月22日 13:52

只要表单中有主键id,编辑保存时候,会排除主键id一样的记录,只比较其他记录。即使字段设置为unique,新增编辑都检验,编辑没有任何修改保存,也是更新成功的。

2014年7月9日 11:17

namespace Home\Model;
use Think\Model;
class ClassifyModel extends Model{
protected $_validate = array(
array(‘name’,’require’,’类名称不能为空’),
array(‘name’,’checkNmae’,’类名称已经存在!换一个吧亲’,0,’unique’,3), // 在新增的时候验证name字段是否唯一
);
function checkName($name){
$where=array(“name”=>$name,isself=>0);
$_GET[‘id’] && $where[‘id’]=$_GET[‘id’];
$r=$this->where($where)->find();
if($r){
return $_GET[‘id’]?true:false;
}else{
return true;
}
}
}

2015年5月15日 17:03

相同的问题

2016年3月24日 12:41

不知道你用的是什么版本,不过 3.2.x 有 验证时间 的选项了,可以在 INSERT 的时候做判断就好了