可能是一个新手问题,但我是自学成才的,而且我正在尝试编辑一些超出我的舒适区域的代码,然后就会失败。请帮忙!
这是一个从MySQL数据库中选择数据并返回数组的函数。它使用了一些其他“核心”函数来帮助建立数据库连接。
原始脚本如下所示:
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()函数中有一个SELECT子句,它将“chat”表与“users”表连接以获取用户名。如果由于某种原因(删除,禁止,退出等),用户表中不存在用户ID,则SELECT子句不返回任何结果。
如果用户不存在仍然要返回消息,我想我需要将JOIN分成2个SELECT CLAUSES:
首先,选择message
,user_id
FROM chat
ORDER BY timestamp
DESC;
然后,如果没有找到行,则选择username
FROM users
WHERE user_id
= $user_id
并返回“Guest”。
(我的脑中有伪代码或逻辑,我只是不能编码!)
我的问题是,因为我使用的是$ this-&gt;符号,我不知道如何在函数内包含第二个实例。我想做的是这样的事情:
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;
}
任何人都可以理解我要做的事情,并重新编写我的伪代码,这样它就不会使用两个'$ this-&gt;'并且实际上有效吗?
我真的很感激任何帮助...
答案 0 :(得分:6)
您只需将JOIN users
更改为LEFT JOIN users
。
您当前的代码执行INNER JOIN
,仅当两个表上有要加入的行时才生成结果行。 LEFT JOIN
将为左侧表中存在的所有行生成结果,在没有对应的情况下用NULL
替换右侧表中的值行存在那里。
在您的情况下,这意味着您将获取所有邮件的行,即使其中某些邮件没有相应的用户。