我需要显示带有数据库响应的注释,因为我需要异步连接,我需要为json数组传输mysql输出。
因此,我的数据库中有两个表,一个是冷注释,另一个是子注释。 我用于显示的代码
$sql = "SELECT comments.* , subcomment.comment AS subcom FROM comments left join subcomment on comments.id = subcomment.forid ";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
$outp = array();
$outp = $result->fetch_all(MYSQLI_ASSOC);
} else {
echo "0 results";
}
但是该代码生成带有多个注释的json,所以如果一个注释有10个响应,我的输出将有10个注释和10个响应,如下所示:
[{
"id":583,
"user_uid":"xxx",
"video_id":"stackoverflow",
"comment":"what did you try?",
"created":"2019-02-19 11:43:15",
"subcom":"nothing special"
},{
"id":583,
"user_uid":"xxx",
"video_id":"stackoverflow",
"comment":"what did you try?",
"created":"2019-02-19 11:43:15",
"subcom":"my sql commands"
},{
"id":583,
"user_uid":"xxx",
"video_id":"stackoverflow",
"comment":"what did you try?",
"created":"2019-02-19 11:43:15",
"subcom":"php? or json"}]
我需要什么? 像这样:
{
"id":583,
"user_uid":"xxx",
"video_id":"stackoverflow",
"comment":"what did you try?",
"created":"2019-02-19 11:43:15",
"subcom":{
sub1: "nothing special" ,
sub2: "my sql commands" ,
sub3: "php? or json"
}}
或者:
{
"id":583,
"user_uid":"xxx",
"video_id":"stackoverflow",
"comment":"what did you try?",
"created":"2019-02-19 11:43:15",
"subcom":["nothing special" , "my sql commands" , "php? or json"]
}
如果有人能告诉我这样做的方法,我会很高兴:D
答案 0 :(得分:1)
您需要将主从关系(“注释”和“子注释”)映射到内存结构上。
您获取主细节记录的方法有点无效,因为您为每个明细行加载了整个主行。我建议将解决方案分成两半,例如首先查询评论,然后仅查询子评论(见下文)。
但是,基本上,根据您提供的查询,您只需要提取一次主数据,然后将详细记录添加到主记录中(如果您已经拥有该主记录)。
要跟踪哪些主记录已添加到结果数组中,我将主记录的主键用作数组键,因为主键可以明确标识该记录。
// Less effective solution - do everything in one query
$sql = "SELECT comments.* , subcomment.comment AS subcom FROM comments left join subcomment on comments.id = subcomment.forid ";
$result = $conn->query($sql);
$outp = array();
foreach ($result->fetch_all(MYSQLI_ASSOC) as $row) {
// we will use primary key as $outp array index
$key = $row['id'];
if (!isset($outp[$key])) {
// this is first time we encountered the master record with that key
// we need to convert detail row into an array
$row['subcom'] = array($row['subcom']);
// save the master record using primary key as index
$outp[$key] = $row;
} else {
// we already encountered master item with key $key,
// so add another comment to the master record that already exist
$outp[$key]['subcom'][] = $row['subcom'];
}
}
// you may want to strip record keys from output array,
// otherwise you will receive hash instead of JSON array
// because keys may be non-sequential and json_encode will interpret
// array as "associative" instead of "numeric"
$outp = array_values($outp);
但是,如果我想提出更有效的解决方案,我会通过以下方式解决它:
// More effective solution - use two queries
$masterQuery = $conn->query("SELECT comments.* FROM comments");
$masterItems = $conn->query($masterQuery)->fetch_all(MYSQLI_ASSOC);
$byKeys = array();
foreach ($masterItems as $row) {
$row['subcom'] = array(); // create array for detail items
$byKeys[$row['id']] = $row;
}
// note: if your keys come from user input, or are not guaranteed
// to be numbers, you will need to sanitize and/or escape
// or quote them on this step
// "forid IN (1, 2, 3)"
$where = 'forid IN ('.implode(', ', array_keys($byKeys)).')';
$detailQuery = "SELECT comment, forid FROM subcom WHERE {$where}";
$detailItems = $conn->query($detailQuery)->fetch_all(MYSQLI_ASSOC);
foreach ($detailItems as $row) {
$masterKey = $row['forid'];
$byKeys[$masterKey]['subcom'][] = $row['comment'];
}
// strip keys from result
$outp = array_values($byKeys);
上面的代码示例只是为了说明原理,因此,如果您只复制并粘贴它们,就不能保证它们能正常工作。