【发布时间】:2021-11-01 00:56:45
【问题描述】:
我的网站有一个使用 PHP 和 mySQL 数据库来存储和提取数据的消息传递系统。
我有一个 _CONVERSATION 表和一个 _MESSAGE 表。前者存储有关与对话关联的收件箱数据的信息。后者比前者弱,并存储包括消息发送日期在内的单个消息数据。当用户加载消息页面时,我希望按用户最近的对话顺序加载收件箱。为此,我创建了一个查询,该查询从 _MESSAGE 表中选择不同的 convoID,该表按 messageID 排序(在按消息日期排序时也可以正常工作,也会出现同样的问题)。
当用户加载消息页面时,我使用所讨论的查询来提取用户参与的最后 10 个对话。我对此使用了限制,并使用 PDO while-fetch 将数据加载到数组中。
这按预期发生,没有问题。
有限制的 PDO SQL:
'SELECT distinct convoID from _MESSAGE where receiverID = :userID or senderID = :userID order by messageID desc limit '.(int)$ext[0].';'
/// userID = 40 (same every time for testing)
/// $ext[0] = 10
/// RESULT: 171, 8, 194, 193, 187, 178, 173, 157, 12, 151 (EXPECTED)
当用户在收件箱中向下滚动时,网站会加载前十个之外的更多对话。我没有限制地运行相同的查询。我运行 while-fetch 直到找到最后一个加载的用户,然后我将接下来的五个项目加载到返回的数组中。一旦加载了五个新项目,我就会跳出 PHP while 循环。
这是我注意到一些奇怪行为的地方。我没有得到预期的结果,并且正在重复一些 convoID。我设置了一个echo $row['convoID'].', '; 来获取完整的查询。
无限制的 PDO SQL:
'SELECT distinct convoID from _MESSAGE where receiverID = :userID or senderID = :userID order by messageID desc;'
/// userID = 40 (same every time for testing)
/// Set up to echo five items after last convoID is found
/// RESULT: 194, 193, 187, 178, 173, 171, 157, 151, 136, 13, 3, 6, 8, 10 (UNEXPECTED)
来自 mySQL 工作台的 SQL:
select distinct convoID from _MESSAGE where receiverID = 40 or senderID = 40 order by messageID desc;
# RETURNS: 171,8,194,193,187,178,173,157,12,151,etc (EXPECTED)
这是我想要并期望从这个查询中得到的回报。
这不是 PDO 第一次按照我的预期启动。我想知道是什么导致了这种奇怪的行为,以及如何在不使用限制的情况下从 PDO 查询中获得预期结果。
我在查询中写错了吗?如果是这样,为什么在 mySQL 工作台中运行相同的精确查询时没有问题?
这里是完整的php函数供参考:
function get_convos($conn, $userID, $ext = ['10','']) {
/// EXT: ['How many to pull','pull all convos after']
$_rtn = [];
$l = 0;
$sql = null;
if ($ext[1] == '') {
$sql = $conn->prepare('SELECT distinct convoID from _MESSAGE where receiverID = :userID or senderID = :userID order by messageID desc limit '.(int)$ext[0].';');
$sql->execute(['userID' => $userID]);
} else {
$sql = $conn->prepare('SELECT distinct convoID from _MESSAGE where receiverID = :userID or senderID = :userID order by messageID desc;');
$sql->execute(['userID' => $userID]);
}
$ready = false;
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
echo $row['convoID'].', ';
$sql2 = $conn->prepare('SELECT * from _CONVERSATION where convoID = :convoID;');
$sql2->execute(['convoID' => $row['convoID']]);
if ($row2 = $sql2->fetch(PDO::FETCH_ASSOC)) {
if ($ext[1] == '') {
$_rtn[$l] = $row2;
$l++;
} else {
if ($ready) {
if ($l < (int)$ext[0]) {
$_rtn[$l] = $row2;
$l++;
} else {
break;
}
}
if ($row2['convoID'] == $ext[1]) {
$ready = true;
}
}
}
}
return $_rtn;
}
感谢你们提供的任何帮助。
【问题讨论】: