3

ユーザー間のブロック機能で問題が発生しました。

SELECT正しい結果を得るためにmy を記述する方法がわかりません。User1 が user2 をブロックすると、両方のユーザーがお互いのプロフィールを見ることができなくなりますが、ログインすると自分のアカウントを見ることができます。これを行うためにスイッチを使用しています。

BLOCKのテーブルはIDUSER1_IDUSER2_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
<? } ?>
4

4 に答える 4

5

クエリの例を求めているようです。

特定のユーザーのペアに対して が「ブロック」(1) に設定されているblockテーブル内の行の存在をテストするクエリが必要なようです。status質問の文言から、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')(どちらの順序でも)、クエリは status = 1 の行を返します。

それ以外の場合、つまり、どちらのユーザーも相手を「ブロック」していない場合、クエリは行を返しません。

クエリでは、指定された 2 つの「user_id」パラメーターをそれぞれ正しい位置で 2 回指定することが重要です。(各引数を 1 回だけ指定する必要があるようにクエリを書き直すことは可能ですが、そのクエリは (私にとって) 理解するのが簡単ではありません。)

于 2012-07-17T20:38:30.763 に答える
3

私はこれがあなたが探しているものだと信じています

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; 
    } 
}
于 2012-07-17T20:28:59.277 に答える
3

残りの回答と同様

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;
}

しかし、あなたの問題はクエリの作成方法にあるとは思いません。それはにあり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;
    }
?> 
于 2012-07-17T20:35:10.927 に答える
1

試す:

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; 
    } 
}

楽しんで頑張ってください!

于 2012-07-17T20:26:05.360 に答える