Создание JSON-дерева родительско-дочерних отношений

#php

#php

Вопрос:

Это мой код, в котором у меня есть три таблицы: таблица сообщений, таблица комментариев и таблица лайков. У меня есть левый соединенный со всеми тремя таблицами postid, общий для всех трех таблиц. Я получаю все данные отлично, но я получаю повторяющиеся данные postdata (например: Postid= 1), я этого не хочу. Моя проблема заключается в получении повторяющихся данных Postdata (например: Postid= 1). Я хочу создать родительский элемент Postdata, где postsdata= 1, и я хочу вставить все данные в родительский элемент

 <?php
    include "../dcon.php";
    $sql = "select * FROM posts left join comments on comments.Cpostid=posts.PostId left join likes on likes.postid=posts.PostId";


        $query=mysqli_query($mysqli,$sql);  
        $result = mysqli_num_rows($query);
        $menus=array();


     for($i=0; $i<$resu< $i  ){
    $row = mysqli_fetch_all($query,MYSQLI_ASSOC);
     foreach($row as $index => $row ){
        $menus[]=[
        'PostId'=>$row['PostId'],
        'PostVideo'=>$row['PostVideo'],
        'PostDesc'=>$row['PostDesc'],
        'PostImage'=>$row['PostImage'],
        'PostedBy'=>$row['PostedBy'],
        'UserName'=>$row['UserName'],
        'Status'=>$row['Status'],
        'PostParent'=>$row['PostParent'],
        'likes'=>$row['likes'],
        'comments'=>[
        $index => [
        'commentsid'=>$row['commentsId'],
        'comments'=>$row['comments'],
        'Cpostid'=>$row['Cpostid'],
        'time'=>$row['time'],
        ],],
        
        'likes'=>[
        $index =>[
        'Likeid'=>$row['Lid'],
        'dislikes'=>$row['dislikes'],
        'postid'=>$row['postid'],
        'userid'=>$row['userid'],
]]
];
        }
     }  
     echo json_encode($menus,JSON_PRETTY_PRINT);

?>
 

Мой вывод был ниже:

 [
    {
        "PostId": "1",
        "PostVideo": "v2.mp4",
        "PostDesc": "this is a tutorial on bench press",
        "PostImage": "null",
        "PostedBy": "Irfan khan",
        "UserName": "irfan",
        "Status": "1",
        "PostParent": null,
        "likes": {
            "Likeid": "1",
            "dislikes": "0",
            "postid": "1",
            "userid": "1"
        },
        "comments": {
            "commentsid": "1",
            "comments": "awesome video",
            "Cpostid": "1",
            "time": "2020-12-16 17:33:33"
        }
    },
    {
        "PostId": "1",
        "PostVideo": "v2.mp4",
        "PostDesc": "this is a tutorial on bench press",
        "PostImage": "null",
        "PostedBy": "Irfan khan",
        "UserName": "khan",
        "Status": "1",
        "PostParent": null,
        "likes": {
            "Likeid": "1",
            "dislikes": "0",
            "postid": "1",
            "userid": "1"
        },
        "comments": {
            "commentsid": "2",
            "comments": "good workouts",
            "Cpostid": "1",
            "time": "2020-12-16 17:33:33"
        }
    },
    {
        "PostId": "1",
        "PostVideo": "v1.mp4",
        "PostDesc": "Chicken generally includes low fat in the meat itself (castrated roosters excluded). The fat is highly concentrated on the skin. A 100g serving of baked chicken breast contains 4 grams of fat and 31 grams of protein, compared to 10 grams of fat and 27 grams of protein for the same portion of broiled, lean skirt steak.",
        "PostImage": "im1",
        "PostedBy": "Rehmat",
        "UserName": null,
        "Status": "1",
        "PostParent": null,
        "likes": {
            "Likeid": "20",
            "dislikes": "0",
            "postid": "1",
            "userid": "4"
        },
        "comments": {
            "commentsid": null,
            "comments": null,
            "Cpostid": null,
            "time": null
        }
    },
    {
        "PostId": "1",
        "PostVideo": "v1.mp4",
        "PostDesc": "Chicken generally includes low fat in the meat itself (castrated roosters excluded). The fat is highly concentrated on the skin. A 100g serving of baked chicken breast contains 4 grams of fat and 31 grams of protein, compared to 10 grams of fat and 27 grams of protein for the same portion of broiled, lean skirt steak.",
        "PostImage": "im1",
        "PostedBy": "Rehmat",
        "UserName": null,
        "Status": "1",
        "PostParent": null,
        "likes": {
            "Likeid": "26",
            "dislikes": "0",
            "postid": "1",
            "userid": "4"
        },
        "comments": {
            "commentsid": null,
            "comments": null,
            "Cpostid": null,
            "time": null
        }
    },
    {
        "PostId": "3",
        "PostVideo": null,
        "PostDesc": "this is an image of chicken",
        "PostImage": "post.jpg",
        "PostedBy": "khan",
        "UserName": null,
        "Status": "0",
        "PostParent": null,
        "likes": {
            "Likeid": null,
            "dislikes": null,
            "postid": null,
            "userid": null
        },
        "comments": {
            "commentsid": null,
            "comments": null,
            "Cpostid": null,
            "time": null
        }
    },
    {
        "PostId": "9",
        "PostVideo": null,
        "PostDesc": "gdhgh",
        "PostImage": "ghghdf",
        "PostedBy": null,
        "UserName": null,
        "Status": null,
        "PostParent": null,
        "likes": {
            "Likeid": null,
            "dislikes": null,
            "postid": null,
            "userid": null
        },
        "comments": {
            "commentsid": null,
            "comments": null,
            "Cpostid": null,
            "time": null
        }
    }
];
 

Я хочу, чтобы мой вывод выглядел следующим образом:

 {
            "PostId": "1",
            "PostVideo": "v2.mp4",
            "PostDesc": "this is a tutorial on bench press",
            "PostImage": "null",
            "PostedBy": "Irfan khan",
            "UserName": "irfan",
            "Status": "1",
            "PostParent": null,
            "likes": 
                '0':{
                "Likeid": "1",
                "dislikes": "0",
                "postid": "1",
                "userid": "1"
            }, 
                '1':{
                "Likeid": "1",
                "dislikes": "0",
                "postid": "1",
                "userid": "1"
            }, 
                '2':{
                "Likeid": "1",
                "dislikes": "0",
                "postid": "1",
                "userid": "1"
            }, 
                '3':{
                "Likeid": "1",
                "dislikes": "0",
                "postid": "1",
                "userid": "1"
            },
            "comments": 
               '0':{
                "commentsid": "1",
                "comments": "awesome video",
                "Cpostid": "1",
                "time": "2020-12-16 17:33:33"
            },
               '1':{
                "commentsid": "1",
                "comments": "awesome video",
                "Cpostid": "1",
                "time": "2020-12-16 17:33:33"
            },
               '2':{
                "commentsid": "1",
                "comments": "awesome video",
                "Cpostid": "1",
                "time": "2020-12-16 17:33:33"
            },
               '3':{
                "commentsid": "1",
                "comments": "awesome video",
                "Cpostid": "1",
                "time": "2020-12-16 17:33:33"
            }
        },
 {
            "PostId": "9",
            "PostVideo": null,
            "PostDesc": "gdhgh",
            "PostImage": "ghghdf",
            "PostedBy": null,
            "UserName": null,
            "Status": null,
            "PostParent": null,
            "likes": {
                "Likeid": null,
                "dislikes": null,
                "postid": null,
                "userid": null
            },
            "comments": {
                "commentsid": null,
                "comments": null,
                "Cpostid": null,
                "time": null
            }
        }
 

Ответ №1:

Хм… Сначала я подумал, что проблема в ваших циклах, и вы неправильно поняли поведение. Но потом я увидел ваше «я хочу, чтобы мой вывод был таким, как показано ниже«, и это не имело смысла, в частности, вы хотели дублировать лайки / комментарии.

Во-первых, циклы: for цикл и внутренний foreach цикл. for Цикл повторяется по количеству результатов. Внутренний foreach цикл повторяет все результаты. Итак, если у нас есть 6 результатов, вместо того, чтобы повторять только 6 раз, мы повторяем 36 раз (6 результатов x 6 результатов).

На самом деле нам нужен только 1 цикл:

 $query = mysqli_query($mysqli, $sql);
$menus = [];
$rows = mysqli_fetch_all($query, MYSQLI_ASSOC);
foreach ($rows as $index => $row) {
    $menus[] = [
        ...
    ];
}
 

Далее мы избегаем дублирования записей, индексируя $menus с PostId помощью . Если PostId еще не существует $menus , мы вставляем сообщение; в противном случае мы просто добавляем лайк / комментарий:

 $query = mysqli_query($mysqli, $sql);
$menus = [];
$rows = mysqli_fetch_all($query, MYSQLI_ASSOC);
foreach ($rows as $row) {
    if (!isset($menus[$row['PostId']])) {
        $menus[$row['PostId']] = [
            'PostId' => $row['PostId'],
            ...
            'comments' => [],
            'likes' => [],
        ];
    }

    $menus[$row['PostId']]['comments'][] = [
        ...
    ];
    $menus[$row['PostId']]['likes'][] = [
        ...
    ];
}
 

Если по какой-то причине вы не хотите $menus индексировать by PostId , мы можем просто вызвать array_values() после цикла, чтобы переиндексировать его последовательным целым числом на основе нуля:

 foreach (...) { ... }
$menus = array_values($menus);
 

Что касается дубликата likes / comments , вы были откровенны об этом. Но на всякий случай, если вы действительно хотите не дублировать, мы также можем индексировать их по их Likeid и commentsid и вставлять / игнорировать по мере необходимости:

 $query = mysqli_query($mysqli, $sql);
$menus = [];
$rows = mysqli_fetch_all($query, MYSQLI_ASSOC);
foreach ($rows as $row) {
    if (!isset($menus[$row['PostId']])) {
        $menus[$row['PostId']] = [
            'PostId' => $row['PostId'],
            ...
            'comments' => [],
            'likes' => [],
        ];
    }

    if (!isset($menus[$row['PostId']]['comments'][$row['commentsid']])) {
        $menus[$row['PostId']]['comments'][$row['commentsid']] = [
            ...
        ];
    }

    if (!isset($menus[$row['PostId']]['Likes'][$row['Lid']])) {
        $menus[$row['PostId']]['Likes'][$row['Lid']] = [
            ...
        ];
    }
}
 

И если мы также не хотим comments , чтобы / likes индексировался commentsid / Lid , мы также можем вызвать array_values() их:

 foreach (...) { ... }
$menus = array_values($menus);
foreach ($menus as amp;$menu) {
    $menu['comments'] = array_values($menu['comments']);
    $menu['likes'] = array_values($menu['likes']);
}
unset($menu);
// Or
array_walk($menus, function (amp;$menu) {
    $menu['comments'] = array_values($menu['comments']);
    $menu['likes'] = array_values($menu['likes']);
});
 

Комментарии:

1. @irfan nw. пожалуйста, примите в качестве ответа. Спасибо.