看起来您正在询问示例查询。
看起来您需要一个查询来测试block
表中是否存在status
针对给定用户对设置为“阻塞”(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
另请注意,如果表中存在冲突行,即一个原始数据表示用户对被“阻止”,而另一行表示该对未被阻止,则“阻止”状态将优先。
请注意,我们甚至不需要返回status
列,我们可以返回一个文字值(使用适当的别名来提供您的代码所期望的结果集元数据。)
看起来您的代码没有任何问题,尽管我可能会对其进行一些不同的编码。重要的是它是可以理解的,并且有效。
更新:
对不起,它不适合你。这是我提供的查询的 SQL Fiddle 演示。
http://sqlfiddle.com/#!2/21120/2
我很可能误解了您试图通过查询完成的任务。我的查询实现的是,如果
- 'foo' 阻止 'bar' 或
- 'bar' 阻止 'foo' 或
- 都互相阻挡
然后当传入('foo','bar')
or的参数时('bar','foo')
(以任意顺序),查询返回状态 = 1 的行。
否则,即如果两个用户都没有“阻止”另一个用户,则查询不返回任何行。
It's important in the query that each of the two supplied "user_id" parameters be supplied twice, in the correct positions. (It's possible to rewrite the query so that each of the arguments only need to be supplied once, but that query isn't as easy (for me) to understand.)