0

I have a two questions with a symfony's project.

My first one : I am trying to modify some data in an array. I have this code

var_dump($results); // FIRST ONE
foreach ($results as $result) {
    foreach ($result as $res) {
        foreach ($dates as $date) {
            if(!array_key_exists($date,$res)) {
                $res = array_merge($res,[$date => '0']);
            }
        }
        var_dump($res); // THIS ONE IS MODIFIED
    }
}
var_dump($results); // LAST ONE... SAME AS THE FIRST ONE

I don't understand why my array ' $results ' is no updated... am i missing something ?

And my second question : is there any way to simplify this code ? I don't like the 3 foreach.

Thanks you guys :)

Peter
  • 777
  • 2
  • 13
  • 34
DavidDG
  • 57
  • 1
  • 7
  • 2
    You need to pass $result and $res by reference if you want to update $results. – Devon Bessemer Jun 29 '18 at 13:46
  • post the dump of the $results variable. how are you getting data into $results ? – Dan Dumitriu Jun 29 '18 at 13:46
  • 4
    Possible duplicate of [PHP foreach change original array values](https://stackoverflow.com/questions/15024616/php-foreach-change-original-array-values) – jbe Jun 29 '18 at 13:46
  • This is how i'm getting data into $results : `foreach ($responses as $response){ $results[$response['code']][] = [$response['date']->format('M') => $response['value']]; }` – DavidDG Jun 29 '18 at 13:54
  • And this is my dump : https://pastebin.com/JUFXqZn3 – DavidDG Jun 29 '18 at 13:58

2 Answers2

2

PHP foreach copy each item when iterate so $result array will not update when you change $res item.

1) You can use array keys to change main array

foreach($arrr as $k => $item) {arrr[$k]['key'] = 'changed'}

2) Or you can get link to the $res item and change it dirrectly

foreach($arrr as &$item) {$item['key'] = 'changed'}

Note that second case can cause different issues

Vladimir Gordienko
  • 3,260
  • 3
  • 18
  • 25
1

Unless you're passing an object in PHP, PHP does not pass values by reference. $res is a copy of the value, not a link to the original value. If you know what you're doing, you can pass by reference. When passing by reference, altering $res would alter the original data. You pass by reference by prefixing a & to the variable or argument.

Since this is a nested foreach, you'll also have to pass $result by reference to avoid that being a copy of the item of $results.

foreach ($results as &$result) {
    foreach ($result as &$res) {
        foreach ($dates as $date) {
            if(!array_key_exists($date,$res)) {
                $res = array_merge($res,[$date => '0']);
            }
        }
    }
}
Devon Bessemer
  • 34,461
  • 9
  • 69
  • 95