Laravel Collection push() not properly working

♀尐吖头ヾ 提交于 2019-12-24 09:57:59

问题


I am trying to duplicate an item in a collection based on the date range. For example, I have a JSON of this:

{
"title": " 200",
"start": "2017-12-20",
"endx": "2017-12-25",
"equipment": "Chairs",
"quantity": 200
}

Now I want to duplicate 6x because there are 6 days from 12-20 to 12-25. Like this:

{
"title": " 200",
"start": "2017-12-20",
"endx": "2017-12-20",
"equipment": "Chairs",
"quantity": 200
}

{
"title": " 200",
"start": "2017-12-21",
"endx": "2017-12-21",
"equipment": "Chairs",
"quantity": 200
}

{
"title": " 200",
"start": "2017-12-22",
"endx": "2017-12-22",
"equipment": "Chairs",
"quantity": 200
}

{
"title": " 200",
"start": "2017-12-23",
"endx": "2017-12-23",
"equipment": "Chairs",
"quantity": 200
}

{
"title": " 200",
"start": "2017-12-24",
"endx": "2017-12-24",
"equipment": "Chairs",
"quantity": 200
}

{
"title": " 200",
"start": "2017-12-25",
"endx": "2017-12-25",
"equipment": "Chairs",
"quantity": 200
}

I want this because of the answer from my previous question: Repeat events on FullCalendar base on date start and end

Here is my code:

$events = Event::all();

        foreach ($events as $i => $event) {
            if($event->start != $event->endx)
            {
                $date = $event->start;
                $end = $event->endx;
                while (strtotime($date) <= strtotime($end)) {
                    $new = [];
                    $new = $event;

                    $new->start = $date;
                    $new->endx = $date;

                    $events->push($new);

                    $date = date ("Y-m-d", strtotime("+1 day", strtotime($date)));
                }
            }
        }

        return $events->all();

But the only output I got is that it repeats 6x based on the last date "2017-12-25". Like this:

{
"title": " 200",
"start": "2017-12-25",
"endx": "2017-12-25",
"equipment": "Chairs",
"quantity": 200
}

{
"title": " 200",
"start": "2017-12-25",
"endx": "2017-12-25",
"equipment": "Chairs",
"quantity": 200
}

{
"title": " 200",
"start": "2017-12-25",
"endx": "2017-12-25",
"equipment": "Chairs",
"quantity": 200
}

{
"title": " 200",
"start": "2017-12-25",
"endx": "2017-12-25",
"equipment": "Chairs",
"quantity": 200
}

{
"title": " 200",
"start": "2017-12-25",
"endx": "2017-12-25",
"equipment": "Chairs",
"quantity": 200
}

{
"title": " 200",
"start": "2017-12-25",
"endx": "2017-12-25",
"equipment": "Chairs",
"quantity": 200
}

回答1:


The problem is:

$new is an object. The $new that you've pushed to that collection is the same $new that you will be using on the next iteration. To further describe the situation:

$a = new stdClass;
$a->name = "foo";

$myArray = [$a];

var_dump($myArray);
// array(1) {
//  [0]=>
//  object(stdClass)#1 (1) {
//    ["name"]=>
//    string(3) "foo"
//  }
//}

$a->name = "bar";
var_dump($myArray);
// array(1) {
//  [0]=>
//  object(stdClass)#1 (1) {
//    ["name"]=>
//    string(3) "bar"
//  }
//}

$new is being passed by reference to the push method, or some would say, assigned by reference.

That's the magic that is happening in your case, to fix that, you should push a cloned object of $new.

You can trace the push code here: https://github.com/laravel/framework/blob/5.5/src/Illuminate/Support/Collection.php#L1129

Change $events->push($new); to $events->push(clone $new);



来源:https://stackoverflow.com/questions/47917157/laravel-collection-push-not-properly-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!