0

I made an array $brands inside class Cars, the print_r output looks like this:

Array ( [0] => Array (  [id] => 1 
                        [name] => 'Porsche'
                    ) 
        [1] => Array (  [id] => 2 
                        [name] => 'Bugatti'
                    ) 
        [2] => Array (  [id] => 3 
                        [name] => 'BMW'
                    ) 
    )

But when I'd like to link to a certain brand, I don't want to use strtolower() to make a lowercased hyperlink. I would like to echo $cars->brands[$i]['url'] (instead of strtolower($cars->brands[$i]['name'])).


class Cars {

So I needed to create a for loop, to create the ['url'] key in the array. I thought that a foreach would work:

foreach ($this->brands as $brand => $row) {
    $row['url'] = strtolower($row['name']);
}

But it didn't. Even this did not work: $row['name'] = strtolower($row['name']);.


But this worked, though:

for ($i = 0; $i < count($this->brands); $i++) { 
    $this->brands[$i]['url'] = strtolower($this->brands[$i]['name']);
}

}


My question here is: how? why?

Derk Jan Speelman
  • 11,291
  • 4
  • 29
  • 45
  • 3
    That's because in your `foreach`-loop, `$row` is actually a _copy_ of the original while in the `for`-loop, your accessing the actual array. – M. Eriksson Mar 30 '17 at 11:25
  • 2
    @MagnusEriksson has the right of it. `foreach($this->brands as &$row)` would work. – Niet the Dark Absol Mar 30 '17 at 11:27
  • You can read this post for an in-depth explanation on how `foreach` works: http://stackoverflow.com/questions/10057671/how-does-php-foreach-actually-work – M. Eriksson Mar 30 '17 at 11:29
  • The concerned concept and solution are also explained in the [docs on `foreach`](http://php.net/manual/en/control-structures.foreach.php) – trincot Mar 30 '17 at 11:30

3 Answers3

4

You need to work on a reference. Insert a & and it will work

foreach ($this->brands as $brand => &$row) {
    $row['url'] = strtolower($row['name']);
}

or you could work on the original array like:

foreach ($this->brands as $brand => $row) {
    $this->brands[$brand]['url'] = strtolower($row['name']);
}
user2659982
  • 131
  • 6
3

if you want to edit the element being iterated you can add a & before $row

foreach ($this->brands as $brand => &$row) {
    $row['url'] = strtolower($row['name']);
}

but this is not necessary, just access the array from the variable available outside of the foreach loop e.g $this->brands

foreach ($this->brands as $brand => $row) {
    $this->brands[$brand]['url'] = strtolower($row['name']);
}
john Smith
  • 17,409
  • 11
  • 76
  • 117
2

because you are overwriting array key('url').

$row is a local copy of $this->brands any changes to $row will not reflect on $this->brands.

change this

foreach ($this->brands as $brand => $row) {
    $row['url'] = strtolower($row['name']);
}

with this

foreach ($this->brands as $brand => $row) {
    $this->brands[$brand]['url'] = strtolower($row['name']);
}

Happy Coding.

Touheed Khan
  • 2,149
  • 16
  • 26