首先,看一看 错误场景:
比如说我们有这样一个编辑界面:
而我们有这样一些验证方法(注:采用的是thinkphp5.0的验证规则)
namespace app\admin\validate; use think\Validate; class Link extends Validate { protected $rule = [ "title" => "require|max:30", "priority" => "require|between:1,100", "url" => "url|require", "des" => "length:1,255", ]; protected $message = [ "title.require" => "标题是必须的", "title.max" => "标题的最大长度为30", "priority.require" => "优先级是必须的", "priority.between" => "优先级必须在1~100之间", "url.url" => "链接地址不合法", "url.require" => "链接地址是必须的", "des.between" => "描述必须在1~255个字符之间" ]; }
比如说我们验证优先级,会要求我们输入的优先级在1~100之间,但如果我们输入的数大于100呢?会发生什么?
如下:
验证不通过!很好,到现在都没有什么问题,但是当等待的时间过去之后,会发生什么?
为什么会发生这样的事情呢?我们来看看edit控制器里面的代码。
public function edit(){ if(request()->isPost()){//如果是表单提交 $data = input("post.");//获取到编辑界面的数据 $validate = Loader::validate("Link");//加载验证器类 if(!$validate->check($data)){//验证数据是否和我们定义的验证规则一致 $this -> error($validate->getError(),"edit","","2"); die; } $linkModel = new LinkModel();
$updateRes = $linkModel -> updateLink(input("post."));//调用LinkModel里面的方法更新数据 if($updateRes){ $this->success("修改成功","index","","1"); }else{ $this->error("修改失败","edit","","1"); } return; } $res=db("link")->where("id",input("id"))->find();//通过最开始点击编辑按钮,然后去数据库查找数据 if($res){ $this->assign("link",$res);//将数据分配给edit界面 }else{ $this->assign("link","");//如果找不到数据则分配给edit界面一个空(不然有可能会报错) } return view();//加载界面 }
看以上代码,到底是哪里出现问题了呢?
我猜想是分配$res数据给界面出了问题。如果$res的数据为空的话,那么我们分配给edit界面的数据就是一个空字符串。
来看看我们的edit界面是怎样获取数据的:
注意,此刻我们的link是空字符串,那么$link.id肯定是取不到值的,所以会报上面所说的那个错?
可是为什么$res会为空呢?如下:
不知道大家有没有注意到这样一句代码:
$res=db("link")->where("id",input("id"))->find();//通过最开始点击编辑按钮,然后去数据库查找数据
当我们验证失败时,重定向到edit界面,此刻我们通过点击编辑按钮传过来的id已经被刷新了,此刻的id是没有值得,所以自然就找不到。那怎么解决呢?
我们验证失败,跳转的代码如下:
if(!$validate->check($data)){//验证数据是否和我们定义的验证规则一致 $this -> error($validate->getError(),"edit","","2"); die; }
在我们验证失败的时候:
if(!$validate->check($data)){ session("redirectId",$data['id']); $this -> error($validate->getError(),"edit","2"); die; }
我们用session将id保存起来,然后在给edit分配数据的时候这样写:
$redirectId = session("redirectId");//从session里面将id取出来 if($redirectId){//判断session是不是为空
$res=db("link")->where("id",$redirectId)->find();//用session里面的id进行查找 } else{ $res=db("link")->where("id",input("id"))->find();//如果session为空,也就是我们的验证没有失败,或者一开始点击编辑按钮进入编辑界面时的情景,用我们点击编辑按钮传入进来的id进行查找 } if($res){ $this->assign("link",$res);//分配数据给模板 }else{ $this->assign("link",""); }
这样,无论怎样从定向我们都能保证查询得到值。但是还有一个问题,当你验证失败时,重定向到编辑界面之后,你不再对编辑界面操作,而是返回到列表页。
此时因为你已经验证失败一次了,所以session里面是有值的,当你点击另外一条数据编辑的时候,还记得上面的代码么?我们首先是判断你的session里面是否有值,而此刻session里面是存在一个id,那么即使我们点击不同的数据,编辑界面显示的还是你的上一条数据。
蛋疼,怎么解决?
其实很简单,在你的列表页的方法将session清空就可以了。如下:
public function index(){ session("redirectId",null);//删除编辑的时候残留的ID $res = db("link") ->order("priority","desc")-> paginate(2); if($res){ $this->assign("linkList",$res); }else{ $this->assign("linkList",array()); } return view(); }
好了,到现在一切都解决了。