微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php – SELECT从user2阻止user1(反之亦然)

我偶然发现我的用户遇到了用户阻止功能的问题.

我不知道如何编写我的SELECT以获得正确的结果.当User1阻止user2时,两个用户都看不到彼此的个人资料,但是当我登录时,我可以看到自己的帐户.我正在使用开关来执行此操作.

我的BLOCK表由ID,USER1_ID,USER2_ID和STATUS组成. 0表示“可见”,1表示“被屏蔽”.

Function.user

public function check_block($user1_id,$user2_id){ 
    $check_sql= "SELECT ......"; 
    $check_query = MysqL_query($check_sql)or die(MysqL_error()); 
    $check_num = MysqL_num_rows($check_query); 
    if($check_num>0){ 
        $block = MysqL_fetch_array($check_query); 
        return $block['status']; 
    }else{ 
        return $check_num; 
    } 
}

开关

<? 
    $user1_id=$_SESSION['id'];
    $user2_id=$data['id'];
    $userblock = function_user_core::check_block($user1_id,$user2_id);
    switch($userblock){
        case 1:
            echo'You Are Blocked From Viewing This Users Profile';
            break;
    }
?>

字段在用户配置文件中被阻止

<? if($userblock==1) { ?> 
    THIS USER HAS BLOCKED YOU FROM THEIR ACCOUNT
<? } ?>

解决方法

看起来你要求一个示例查询.

看起来您需要一个查询来测试块表中是否存在行,其中状态对于给定的一对用户设置为“已阻止”(1).根据您的问题的措辞,看起来user_id值的顺序无关紧要. (对于此查询)是否’foo’阻止’bar’或’bar’阻止’foo’,或两者兼而有之.看起来您的代码将在所有这些情况下执行相同的确切路径. (如果我理解你的问题.)

这个查询应该得到:

SELECT b.status
  FROM block b
 WHERE ( b.status = 1 AND b.user1_id = 'foo' AND b.user2_id = 'bar' )
    OR ( b.status = 1 AND b.user1_id = 'bar' AND b.user2_id = 'foo' )
 LIMIT 1

注意:此查询不考虑用户已阻止自己的极端情况.请参阅下面的查询以处理该条件.

我在我的示例查询中使用了文字’foo’和’bar’,您当然可以在sql文本中替换(正确转义的)变量.

对于此检查查询,只有在找到指定给定的一对用户被“阻止”的行时,才需要返回一行.否则,查询不需要返回任何行.通过此查询,您的代码实际上可以更简单一些.使用此查询,您只需从MysqL_num_rows返回值即可.

也就是说,您可以替换此块:

$check_num = MysqL_num_rows($check_query); 
if($check_num>0){ 
    $block = MysqL_fetch_array($check_query); 
    return $block['status']; 
}else{ 
    return $check_num; 
}

有了这个:

$check_num = MysqL_num_rows($check_query); 
return $check_num;

上面的查询没有说明用户已阻止自己的(异常?)角落情况.

如果表包含这样的行:

('foo','foo',1)

并且您将’foo’和’foo’的值传递为user_1和user_2,上面的查询将返回一行.但是您指定用户应始终能够查看自己的配置文件.

因此,如果要忽略指定用户从自己的配置文件中“阻止”自己的条件的任何行,则可以在查询添加一个谓词,以简单地忽略user_id值匹配的任何行:

SELECT 1 AS `status`
  FROM block b
 WHERE b.user1_id <> b.user2_id
   AND b.status = 1
   AND (  ( b.user1_id = 'foo' AND b.user2_id = 'bar' )
       OR ( b.user2_id = 'foo' AND b.user1_id = 'bar' )
       )
 LIMIT 1

另请注意,如果表中存在冲突的行,即一个表示用户对被“阻止”的原始行和另一行表示该对未被阻止的行,则“阻止”状态将优先.

请注意,我们甚至不需要返回状态列,我们可以返回一个文字值(使用适当的别名来提供代码期望的结果集元数据.)

看起来您的代码中没有任何问题,但我可能会对它进行不同的编码.重要的是它是可以理解的,并且它是有效的.

更新:

对不起,它不适合你.这是我提供的查询sql fiddle演示.
http://sqlfiddle.com/#!2/21120/2

我很可能误解了你试图用你的查询完成的事情.我的查询实现的是,如果

>’foo’阻止’bar’或
>’bar’阻止’foo’或
>两者互相阻挡

然后当传入参数(‘foo’,’bar’)或(‘bar’,’foo’)(按任意顺序)时,查询返回一个status = 1的行.

否则,即如果两个用户都没有“阻止”另一个,则查询不返回任何行.

查询中,重要的是两个提供的“user_id”参数中的每一个都在正确的位置提供两次. (可以重写查询,以便每个参数只需要提供一次,但该查询对我来说并不那么容易理解.)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐