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的实现,有更好的方法或思路,欢迎留言交流!