我偶然发现了一个用户到用户块功能的问题。
我不知道如何编写SELECT
以获得正确的结果。当User1阻止user2时,两个用户都看不到对方的个人资料,但当我登录时,我可以看到自己的帐户。我用开关来做这个。
我的BLOCK
表由ID
、USER1_ID
、USER2_ID
和STATUS
组成。0
为"可查看",1
为"阻止"。
功能。用户
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
<? } ?>
看起来您在询问一个示例查询。
看起来您需要一个查询来测试block
表中是否存在一行,其中对于给定的一对用户,status
设置为"blocked"(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"answers"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
还要注意,如果表中有冲突的行,即一行表示用户对"被阻止",另一行表示该对未被阻止,则"已阻止"状态将优先。
请注意,我们甚至不需要返回status
列,我们可以返回一个文字值(使用适当的别名来提供代码所需的结果集元数据)
看起来你的代码没有任何问题,尽管我可能会对它进行一些不同的编码。重要的是,这是可以理解的,而且它是有效的。
更新:
对不起,这对你不起作用。下面是我提供的查询的SQLFiddle演示。
http://sqlfiddle.com/#!2/21120/2
很可能是我误解了您的查询目的。我的查询实现的是,如果
- "foo"阻止"bar"或
- "bar"阻止"foo"或
- 两者互相阻挡
则当传入参数('foo','bar')
或('bar','foo')
(按任意顺序)时,查询返回状态为1的行。
否则,也就是说,如果两个用户都没有"阻止"另一个,则查询不返回任何行。
在查询中,两个提供的"user_id"参数中的每一个都要在正确的位置提供两次,这一点很重要。(可以重写查询,这样每个参数只需要提供一次,但该查询(对我来说)并不容易理解。)
我相信这就是您想要的
SELECT `STATUS` FROM `BLOCK` WHERE `USER1_ID`=X AND `USER2_ID`=Y;
功能将是
public function check_block($user1_id,$user2_id){
$check_sql= "SELECT `STATUS` FROM `BLOCK` WHERE `USER1_ID`=$user1_id AND `USER2_ID`=$user2_id;";
$check_query = mysql_query($check_sql)or die(mysql_error());
$check_num = mysql_num_rows($check_query);
if($check_num>0){
$block = mysql_fetch_assoc($check_query);
return (int)$block['status'];
}else{
return $check_num;
}
}
类似于的其他答案
public function check_block($user1_id,$user2_id){
$check_sql= "SELECT * FROM BLOCK WHERE USER1_ID = '$user1_id' AND USER2_ID = '$user2_id' AND STATUS = 1";
$check_query = mysql_query($check_sql)or die(mysql_error());
$check_num = mysql_num_rows($check_query);
return $check_num;
}
但我不认为您的问题在于如何构造Query。它位于Switch
;由于您希望user1检查user2是否阻止了user1,因此需要颠倒传递到函数中的变量的顺序。
<?php
$user1_id=$_SESSION['id'];
$user2_id=$data['id'];
$userblock = function_user_core::check_block($user2_id, $user1_id);
switch($userblock){
case 1:
echo'You Are Blocked From Viewing This Users Profile';
break;
}
?>
尝试:
public function check_block($user1_id,$user2_id) {
$check_sql= "SELECT STATUS FROM BLOCK WHERE USER1_ID = '" . mysql_real_escape_string($user1_id) . "' AND USER2_ID = '" . mysql_real_escape_string($user2_id) . "'";
$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;
}
}
祝你好运!