0

おそらく少し初心者の質問ですが、私は独学で、自分の快適ゾーンから外れたコードを編集しようとしていますが、うまくいきません。助けてください!

MySQLデータベースからデータを選択し、配列を返す関数です。DB接続を支援するために、他のいくつかの「コア」機能を使用します。

元のスクリプトは次のようになります。

class Core{
    protected $db, $result;
    private $rows;

    public function __construct() {
        $this->db = new mysqli('localhost', 'root', 'password', 'db');
    }

    public function query($sql){
        $this->result = $this->db->query($sql);
    }

    public function rows(){
        for($x = 1; $x <= $this->db->affected_rows; $x++){
            $this->rows[] = $this->result->fetch_assoc();
        }
    return $this->rows;
    }
}

class Chat extends Core{
    public function fetchMessages(){
        $this->query("
            SELECT  `chat`.`message`,
                    `users`.`username`,
                    `users`.`user_id`
            FROM    `chat`
            JOIN    `users`
            ON      `chat`.`user_id` = `users`.`user_id`
            ORDER BY `chat`.`timestamp`
            DESC
        ");
        return $this->rows();
    }
}

問題は、Chat クラスの fetchMessages() 関数内に、「chat」テーブルと「users」テーブルを結合してユーザー名を取得する SELECT 句があることです。何らかの理由 (削除、禁止、終了など) で、ユーザー ID がユーザー テーブルに存在しない場合、SELECT 句は結果を返しません。

ユーザーが存在しない場合でもメッセージを返すには、JOIN を 2 つの SELECT 句に分ける必要があると思います。

  • まず、 SELECT messageuser_idFROM chatORDER BY timestampDESC;

  • 次に、行が見つからない場合は、SELECT usernameFROM usersWHERE user_id=および RETURN "Guest" を実行します。$user_id

(疑似コードまたはロジックは頭の中にありますが、それをコーディングすることはできません!)

私の問題は、$this-> 表記を使用しているため、関数内に 2 番目のインスタンスを含める方法がわからないことです。私がやりたいことは次のようなものです:

public function fetchMessages(){
    $this->query("
        SELECT `message`, `user_id` FROM `chat` ORDER BY `chat`.`timestamp` DESC
    ");
    $rows = $this->rows();
    foreach ($rows as $row) {
        $uid = $row['user_id'];

        $this[2]->query("
            SELECT `username` FROM `users` WHERE `user_id` = `$uid`;
        ");
        $user = $this[2]->rows();

        if ( $user['username'] == "" ) {
            $username = "Guest";
        } else {
            $username = $user['username'];
        }
        $return_array[] = array($row['message'],$username);
    }
    return $return_array;
}

誰かが私がやろうとしていることを理解し、疑似コードを書き直して、2 つの '$this->' を使用せず、実際に機能するようにすることはできますか?

何か助けていただければ幸いです...

4

1 に答える 1

6

JOIN usersに変更するだけですLEFT JOIN users

現在のコードは、両方のテーブルINNER JOINに結合する行がある場合にのみ結果行を生成する を実行します。は、左側のテーブルに存在するすべての行の結果を生成し、対応する行がそこに存在しない場合、右側のテーブルの値を置き換えます。LEFT JOINNULL

あなたの場合、これは、一部のメッセージに対応するユーザーがいない場合でも、すべてのメッセージの行を取得することを意味します。

SQL 結合の視覚的な説明も参照してください。

于 2013-03-12T11:34:00.273 に答える