PHP分销推广如何确立上下级关系,【解决方案+问题分析】微信分销会员上下级关系出现混乱,剖析全过程...

微信分销会员上下级关系出现混乱,从反馈到分析问题如何发生 ,再到如果解决。在此把实际项目遇到的问题分享出来,以供以后和网友参考。

某日,接到一通领导打来的一通电话。电话主要内容是他曾接到一个用户的反馈电话,说道我们有一个项目中,微信会员上下级关系存在混乱,用户a关注的用户b,用户b却关注的用户的a。上下级关系很乱,还有很多用户存在一些,用户a关注了用户b,用户b的推荐好友列表中却没有用户a的存在……

当我拿到这个问题之后,首先的态度很是质疑,代码应该都是没有问题的,可能会存在一些数据没有对上。此处我需要在整个数据库中查找出所有的上下级混乱关系的会员。

什么是上下级混乱关系?

用户b的上级是用户a,用户a的上级是用户b。(b>a>b)

用户c的上级是用户b,用户b的上级是用户a,用户a的上级是用户c。(c>b>a>c)

所谓的混乱便是出现了这种无线循环的关系,那么,如果查找出来这种上下级关系呢?

怎么解决?

根据以上的举例,能够很明显的能看出来一个规律便是这种会员关系中,一圈之中至少存在两个会员的?自己上级的上级……的上级有可能是自己。只要找出自己所有的上级来查询是否存在两个相同会员就好了。

首先写一个脚本来执行,如果web执行超时,可采用命令行方式执行。

以下以TP框架语法进行举例:

/**

* 排错函数

*/

public function member_level(){

$Model = M('weishop_member');

//查询出所有有上级的用户

$exist_sql = "SELECT wm_id,wm_parent_id FROM weishop_member WHERE wm_parent_id !=0";

$exist_parent_users = $Model->query($exist_sql);

//debug_show($exist_parent_users);

$num = 0;

$error_users = array();

foreach($exist_parent_users as $val){

//此处屏蔽的代码可以在调试时放开,测试数据是否正常,避免逻辑错误导致死循环超时

//if($num==2){

//exit;

//}

$user_status = $this->level_debug($val['wm_id'],$val['wm_parent_id'],true);

if($user_status===3){

$error_users[] = $val['wm_id'];

}

$num++;

}

echo '
error users:'.implode(',', $error_users).'
';

echo '
Check OK!';

//拿出一个数据来进行 测试排错

//$this->level_debug($exist_parent_users[0]['wm_id'],$exist_parent_users[0]['wm_parent_id'],true);

echo 'Exist users number:'.count($exist_parent_users);

}

/**

* 递归排错

* @desc  查询当前用户的上级祖(祖父)中是否存在循环(儿子)

* @param  $wm_id     会员id

* @param  $parent_id 上级id

* @param  $init      是否初始化,即首次执行

* @return  1:用户正常。0:用户还有上级。3:用户关系出错

*/

private function level_debug($wm_id,$parent_id,$init=false){

static $user_id = 0;//被检查的用户

static $_son = array();//儿子组

static $num = 0;//循环执行次数

//empty  如果是初始化执行则清空

if($init){

$_son = array();

$num = 0;

$user_id = $wm_id;

}

$num++;

if(!isset($_son[$wm_id])){

//如果儿子组中不存在当前用户,则加入当前用户,继续向下查找祖父

$_son[$wm_id] = array(

'wm_id'=>$wm_id,

'wm_parent_id' => $parent_id

);

}

//调试时测试执行次数,防止逻辑错误,出现死循环超时

if($num==5){

//debug_show($wm_id);

//debug_show($_son);

}

$Model = M('weishop_member');

//查询当前上级

$query_parent_sql = "SELECT wm_id,wm_parent_id FROM weishop_member WHERE wm_id = '$parent_id'";

$parent_user = $Model->query($query_parent_sql);

//如果上级存在 并且上级用户还有上级则继续递归

//条件:1.当前用户上级存在。2.上级用户还存在上级

if(is_array($parent_user) && isset($parent_user[0]) && $parent_user[0]['wm_parent_id']!=0){

$buf = $parent_user[0];

//如果当前用户上级的上级存在于儿子组中则进入判断

if(isset($_son[$buf['wm_parent_id']])){

echo 'error! user id:'.$user_id.'  '.'parent_id :'.$buf['wm_id'].'  '.'parent includes '

.implode(',', array_keys($_son)).' execute:'.$num .'
 ';

return 3;

//exit;

}

//符合条件 继续进入循环探寻祖父

$this->level_debug($buf['wm_id'],$buf['wm_parent_id']);

return 0;

}

//数据量过多,则关闭正常用户结果显示

//echo 'user id:'.$user_id.'  '.'parent_id :'.$parent_id.'  '.'parent includes '

//.implode(',', array_keys($_son)).' execute:'.$num .'
 ';

return 1;

}

以上代码经过多次修改后的,并不是一气呵成。需要用到的朋友可以仔细分析下逻辑。

经过多次的修改,以上的代码没有超时执行,跟用户数量还是有关系,毕竟只有几千个。返回的内容如下:

91a0f54cb387f35ffd4f66022155d373.png

说明一下,红色error都是关系混乱的用户,在最后我们可以看到出错的用户抱(bāo)括2和116。所存在上级的用户总共有3158个。

那么问题看来都是由2和116的关系混乱导致的,只需要将他们更正后即可。之后便联系了用户id分别为2和116的用户,将他们的注册时间和推荐时间做一了解,将2的上级清空,恢复为0.

那么再执行刚才的排错来看看结果。

52b989f88a4592cb0db253faf74478fe.png

这次检查之后,发现并没有关系混乱的用户。一切恢复平静。虽然说目前的问题解决了,但并不意味着,以后都会正常,问题的根源还没有找出来。

怎么修复?

带着问题继续在代码中寻找,来到会员绑定的逻辑处。

/**

* 绑定微信上下级(未修复)

* @param   $openid    当前用户openID

* @param   $parent_id 上级用户id

* @return  bool

*/

public function bingding($openid,$parent_id){

//检测当前用户是否有上级并且上级不能为自己,没有则继续

$res = $this->where("wm_openid ='$openid' && wm_id != '$parent_id' && wm_parent_id ='0'")->save(array("wm_parent_id" => $parent_id));

if($res){

return true;

}

}

粗略一看几乎看不出来啥问题,绑定时首先判断的是当前用户的上级是否存在,如果有自然不能附加上级了。如果没有的情况下,并且上级不能为自己,否则自己跟自己成为上级就乱了套。当时写的代码本以为是正常。结果出了一个隐性bug。

怎么发生的呢?

上面的逻辑会忽略掉,下级下级的用户偶然一天变成自己的上级(可能是因为自己失误的去扫码,扫了自己辛辛苦苦下级用户的码,反而让下级成为了自己的上级),导致关系混乱,在用户方面可能会导致佣金等利益计算错误,在平台层面会影响一笔损失,在此可以给各位一个提醒,凡是跟钱有关的一定要慎重!

至于修复呢,而此处只需要增加一层判断即可解决。

修改后代码奉上:

/**

* 绑定微信上下级(已修复)

* @param   $openid    当前用户openID

* @param   $parent_id 上级用户id

* @return  bool

*/

public function bingding($openid,$parent_id){

//检测是否有下级

$sql = "SELECT count(a.wm_id) as count FROM `weishop_member` as a  join `weishop_member` as b on a.wm_parent_id = b.wm_id WHERE b.wm_openid='{$openid}';";

$count_res = $this->query($sql);

if(is_array($count_res) || count($count_res)==1){

if(isset($count_res[0]['count']) && $count_res[0]['count']>0){

return false;

//如果有下级则不能成为别人的下级

}

}

//检测当前用户是否有上级并且上级不能为自己,没有则继续

$res = $this->where("wm_openid ='$openid' && wm_id != '$parent_id' && wm_parent_id ='0'")->save(array("wm_parent_id" => $parent_id));

if($res){

return true;

}

return false;

}

如果自己已经有了下级用户就不能成为别人的下级,这样一来,就不会出现这种死循环。当然解决的方案不只是这一个,符合业务逻辑就好。

修改好代码检查无误后立即将代码更新至服务器,以防止出现更多差错。

基本上此次的bug检查及解决方案就到此结束了,过程中一些细节性东西不太好描述,最好去实际实践一下,或者是实际用到时慢慢体会。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值