如何在php

时间:2018-06-16 05:58:31

标签: php arrays laravel for-loop

我正在构建一个[post,comments]项目,其中帖子详细信息存储在posts表中,注释详细信息存储在comments表中。该项目由Laravel(Php)生成。这是一段代码。

//get data from Post table
$posts = $this->postsRepo->getAllPosts();
//get data from comments table
$comments = $this->commentRepo->getAllComments();
print_r($posts);
print_r($comments);

发布表的结果

Array
(
    [0] => stdClass Object
        (
            [id] => 1
            [post_text] => This is a test post
        )
)
    [1] => stdClass Object
        (
            [id] => 2
            [post_text] => This is another test
        )
)

评论表的结果

Array
(
    [0] => stdClass Object
        (
            [id] => 1
            [post_id] => 1
            [comments_text] => This is a test comment 1
        )
    [1] => stdClass Object
        (
            [id] => 2
            [post_id] => 1
            [comments_text] => This is a test comment 2
        )
)

现在我想要像

这样的结果
Array
(
    [0] => stdClass Object
    (
        [id] => 1
        [post_title] => This is a test post         
        [comments] => Array
            (
                [0] => stdClass Object
                    (
                        [id] => 1
                        [post_id] => 1
                        [comment_text] => This is a test comment 1
                    )

                [1] => stdClass Object
                    (
                        [id] => 2
                        [post_id] => 1
                        [comment_text] => This is a test comment 2 
                    )
            )
        )
    )
    [1] => stdClass Object
    (
        [id] => 2
        [post_title] => This is another test
        [comments] => Array()
    )

)

我使用了以下技术,它正在运作

foreach ($posts as $postIndex => $post) {
    foreach ($comments as $commentIndex => $comment) {
        if($post->id == $comment->post_id) {
            $posts[$postIndex]->comments[] = $comment;
        }
    }
}

还有其他方法可以在发布 for循环中运行评论。我将post_id发送到评论表。但随着数据的增加,这项技术将变得缓慢

有人可以建议更好的技术来解决这个问题吗? 另外,我使用Repository设计模式获取帖子和&评论

3 个答案:

答案 0 :(得分:1)

有几种方法可以执行此操作,具体取决于您使用的PHP版本(尽管1将始终有效)。主要原则是通过ID索引其中一个数组,这样您就可以使用索引来设置值,而不是循环遍历两个数组。由于每个帖子都可以有多个评论,因此通过ID索引帖子并在评论中循环,将它们添加到正确的帖子中似乎更容易......

$posts = [
    (object)[
        "id" => 1,
        "post_text" => "This is a test post"
    ],
    (object)[
        "id" => 2,
        "post_text" => "This is another test"
    ]
];

$comments = [(object)
    [
        "id" => 1,
        "post_id" => 1,
        "comments_text" => "This is a test comment 1"
        ],
    (object)
    [
        "id" => 2,
        "post_id" => 1,
        "comments_text" => "This is a test comment 2"
        ]
    ];

$postIndex = array_column($posts, null, "id");   
//$postIndex = array_reduce($posts, function ($result, $post) { // PHP pre 7
//    $result[$post->id] = $post;
//    return $result;
//}, array());
foreach ( $comments as $comment )   {
    $postIndex[ $comment->post_id ]->comments[] = $comment;
}
echo "<pre>";
print_r($postIndex);

...输出

Array
(
    [1] => stdClass Object
        (
            [id] => 1
            [post_text] => This is a test post
            [comments] => Array
                (
                    [0] => stdClass Object
                        (
                            [id] => 1
                            [post_id] => 1
                            [comments_text] => This is a test comment 1
                        )

                    [1] => stdClass Object
                        (
                            [id] => 2
                            [post_id] => 1
                            [comments_text] => This is a test comment 2
                        )

                )

        )

    [2] => stdClass Object
        (
            [id] => 2
            [post_text] => This is another test
        )

)

唯一的区别是,从PHP 7.0开始,您可以将array_column()与对象数组一起使用。在此之前,您必须手动进行转换。

答案 1 :(得分:0)

你最好使用雄辩的关系...... 但要回答你当前案件的问题,如果你需要用php方式完成这个。

// for all the post of the posts array
    foreach ($posts as $key => $value) {

        // get comments which only belongs to the post
        $post_comments = [];
        foreach ($comments as $comment) {

            if ($comment['post_id'] == $value['id']) {
                array_push($post_comments, $comment);
            }
        }

        // add a new attribute (comments) to each post
        // set created comments array of the post
        $post[$key]['comments'] = $post_comments;
    }

答案 2 :(得分:0)

如果您循环发布,则可以使用array_intersect和array_intersect_key 这意味着您只需循环一个数组,但使用数组函数来获取正确的注释 这意味着数组必须是数组而不是对象。

Foreach($posts as $key => $post){
    $matches = array_intersect(array_column($comments, "post_id"), [$post["id"]]);
    $new[$key][] = $post;
    $new[$key]["comments"][] = array_intersect_key($comments, $matches);
}

Var_dump($new);

https://3v4l.org/eq20D