php 如何生成path及其日常维护?
php 如何生成path及其日常维护
path字段重要性不言而喻,在查询的时候,如果只用pid,查询效率会很低,增加path,查询效率大大提高,最起码不用递归查库了,重点是维护推荐关系的时候要维护path以及更改。
在path分隔符中,建议使用英文','号,方便查询。切记使用like,最好是使用find_in_set
一、path字段
1、首先是在会员表中,得有path字段,一些情况下,path字段会比较长,建议类型为text,不建议varchar
2、当推荐新会员的时候,借助父级的path,后面拼接上父级的id,就是新会员的path
1 $path = $path ? $pid . ',' . $path : $pid;
二、后台修改推荐人
这种情况是比较麻烦的,就是后台想更改某会员的父级,如果单纯的只有pid,只更改pid就行了,但是存在path,更改当前会员pid和path的同时,当前会员所有团队成员的path也得更改。
这里存在当前会员之前有上级和之前没有上级两种情况
1、已有上级,这时候所有团队成员的path为当前会员新path再拼接上当前会员的id,再拼接上下级之前的path中截取当前用户id之后的部分
2、没有上级,那所有团队成员的新path就简单了,直接为当前会员新path,直接拼接上下级的path即可
1 if ($params['pid'] && $params['pid'] != $row['pid']) { 2 //说明选择了新上级,而且确实和之前上级不一样了,如果新上级和之前上级一样,无需更新path 3 //首先验证pid不在目标子串中 4 $arr = explode(',',$puser['path']); 5 if ($arr && in_array($ids,$arr)) { 6 $this->error('自己下级不能成为新上级'); 7 } 8 //更新当前会员自己的pid和path, 9 $params['path'] = $puser['path'] ? $puser['path'] . ',' . $params['pid'] : $params['pid']; 10 if ($row['pid']) { 11 //说明当前会员之前就有上级, 12 //则所有下级的新path为$params['path'] 再拼接上当前会员的id,再拼接上下级之前的path中截取当前用户id之后的部分 13 $sql = "update sn_user set path = (CONCAT('".$params['path']."',',',".$ids.",SUBSTRING_INDEX(path,".$ids.",-1))) where FIND_IN_SET(".$ids.",path)"; 14 } else { 15 //说明当前会员之前没有上级,那所有下级的新path就简单了,直接为$params['path'],直接拼接上下级的path即可 16 $sql = "update sn_user set path = (CONCAT('".$params['path']."',',',path)) where FIND_IN_SET(".$ids.",path)"; 17 } 18 $this->model->query($sql); 19 } else { 20 unset($params['pid']); 21 }
三、在无path下如何增加path
这种情况一般发生在已有一些会员的情况下,如果会员不多,自己手动改就行,当然,如果会员量比较大的话,手动就费劲了,所以有时候写一个脚本也是挺管用的。
1、首先在会员表新增path字段,默认为空值,然后新建一个标识path_status,在会员量大的时候进行分段查询
2、借助脚本,更新path,这里写的了一个递归查询,如有更好的方法,欢迎留言交流!
1 /* 2 * 更新path字段 3 */ 4 public function update_path() 5 { 6 //更新所有的用户的path] 7 $users = Db::name('member') 8 ->where([ 9 'pid'=>['gt',0], 10 'path_status'=>0, 11 ]) 12 ->field('id,pid,path') 13 ->limit(100)->select(); 14 $count = 0; 15 foreach ($users as $v) { 16 //计算path,修改path_status为1 17 $path = $this->get_path(0,$v['pid']); 18 //$path = '0-'.$path;//拼接上顶级0 19 Db::name('member')->where('id',$v['id'])->update(['path'=>$path,'path_status'=>1]); 20 $count++; 21 } 22 echo $count;die; 23 }
这里是获取path的方法:
1 /* 2 * 递归查库,获取上级pid 3 */ 4 public function get_path($path,$pid) 5 { 6 $path = $path ? $pid.'-'.$path : $pid; 7 $rid = Db::name('member')->where('id',$pid)->value('pid'); 8 if ($rid) { 9 return self::get_path($path,$rid); 10 } 11 return $path; 12 }
如果对于path的实现,有更好的方法或思路,欢迎留言交流!