简体   繁体   English

PHP数组在foreach语句 - 范围问题中消失了吗?

[英]PHP array vanishes in foreach statement - scope issue?

So, I have this very weird error - Some advanced PHP devs might also be considered somewhat weird. 所以,我有这个非常奇怪的错误 - 一些高级PHP开发人员也可能被认为有些奇怪。

In the 2nd foreach statement I have an array "$reply_each" created in that foreach statement and it is supposed to be "array_push()"-ed into another array called "$recent_discussion_each['discussion_replies_array']". 在第二个foreach语句中,我在该foreach语句中创建了一个数组“$ reply_each”,它应该是“array_push()” - 编入另一个名为“$ recent_discussion_each ['discussion_replies_array']”的数组中。 This works while in the 2nd foreach statement. 这在第二个foreach声明中有效。 But as soon as the 2nd foreach statement finishes, the "$reply_each" array just vanishes - as if it was out of scope. 但是,只要第二个foreach语句结束,“$ reply_each”数组就会消失 - 好像它超出了范围。 Just to be sure it wasn't a scope issue, I initialized $reply_each at the beginning of the function but that didn't help - it must be something else. 为了确保它不是范围问题,我在函数的开头初始化了$ reply_each,但这没有帮助 - 它必须是其他东西。

Help, please? 请帮助?

Update: I probably should add that when I do a count() on $recent_discussion_each['discussion_replies_array'] inside the 2nd foreach statement, I get the correct value of 1. But when I do an identical count(), but this time outside of the 2nd foreach statement, I get an incorrect value of 0. This is the problem, if it wasn't clear before. 更新:我可能应该补充一点,当我在第二个foreach语句中对$ recent_discussion_each ['discussion_replies_array']执行count()时,我得到正确的值1.但是当我执行相同的count()时,但这次在外面在第二个foreach语句中,我得到一个不正确的值0.这是问题,如果以前不清楚的话。

public function getRecentDiscussions($num_recent_discussions, $course_id) {
    //
    $this->load->database();
    //
    $recent_discussions_array = array();
    //
    // Construct query to fetch recent discussions along with their replies and some
    // basic user info about the authors
    $query_recent_discussions = $this->db->select('course_discussion.id AS course_discussion_id,
                                                   user.f_name,
                                                   user.l_name,
                                                   course_discussion.text,
                                                   course_discussion.posted_datetime,
                                                   course_discussion.is_reply,
                                                   course_discussion.parent_id
                                                  ')
                                         ->join('user', 'course_discussion.owner = user.id')
                                         ->where('course_discussion.course', $course_id)
                                         ->limit($num_recent_discussions)
                                         ->get('course_discussion');
    //
    foreach($query_recent_discussions->result_array() as $row) {
        //
        // Figure out of this comment is a parent or a reply. If it is a parent (meaning is_reply
        // is equal to 0), then treat it like one
        if($row['is_reply'] == '0') {
            //
            $recent_discussion_each = array();
            //
            $recent_discussion_each['discussion_id'] = $row['course_discussion_id'];
            $recent_discussion_each['discussion_owner_f_name'] = $row['f_name'];
            $recent_discussion_each['discussion_owner_l_name'] = $row['l_name'];
            $recent_discussion_each['discussion_body'] = $row['text'];
            $recent_discussion_each['discussion_posted_datetime'] = $row['posted_datetime'];
            $recent_discussion_each['discussion_replies_array'] = array();
            //
            array_push($recent_discussions_array, $recent_discussion_each);
        }
        //
        // Else, it must be a reply since is_reply is not a 0
        else {
            //
            // Look for the parent comment by going through the entire list of comments
            foreach($recent_discussions_array as $potential_parent) {
                //
                // Check to see if this comment's (now known as a reply's) id matches 
                // the id of the comment currently in the position in the list of comments
                if($row['parent_id'] == $potential_parent['discussion_id']) {
                    //
                    $reply_each = array();
                    //
                    $reply_each['reply_id'] = $row['course_discussion_id'];
                    $reply_each['reply_owner_f_name'] = $row['f_name'];
                    $reply_each['reply_owner_l_name'] = $row['l_name'];
                    $reply_each['reply_text'] = $row['text'];
                    $reply_each['reply_posted_datetime'] = $row['posted_datetime'];
                    $reply_each['reply_is_reply'] = $row['is_reply'];
                    $reply_each['reply_parent_id'] = $row['parent_id'];
                    //
                    array_push($potential_parent['discussion_replies_array'], $reply_each);
                }
            }
        }
    }
    //
    foreach($recent_discussions_array as $recent_discussion) {
        echo ($recent_discussion['discussion_id'].' has the following replies: ');
        foreach($recent_discussion['discussion_replies_array'] as $reply) {
            echo($reply['reply_id']);
        }
    }
    //
    return $recent_discussions_array;
    //
    // end
    //
}

foreach creates a copy of items for usage inside the loop body. foreach在循环体内创建用于使用的项目副本。 What this means is that $potential_parent is not actually the original arrays from $recent_discussions_array , but copies of them. 这意味着$potential_parent实际上不是来自$recent_discussions_array的原始数组,而是它们的副本。

Thus, when you modify them, as soon as the foreach($recent_discussions_array as $potential_parent) loop finishes, those copies go away. 因此,当您修改它们时,只要foreach($recent_discussions_array as $potential_parent)循环结束,这些副本就会消失。

As a simplified example of what I mean, note the distinct lack of any "baz" printing here: 作为我的意思的简化示例,请注意这里明显缺少任何“baz”打印:

http://ideone.com/WlDru http://ideone.com/WlDru

Then compare to what happens if you actually access the original array by key: 然后比较实际按键访问原始数组时会发生什么:

http://ideone.com/etvr5 http://ideone.com/etvr5

What you really probably want, as Ben points out in the comments, is to use the & operator: 正如Ben在评论中指出的那样,你真正想要的是使用&运算符:

http://ideone.com/2TphI http://ideone.com/2TphI

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM