2

I've started teaching myself php and have found something I don't understand. If it is really simple, my apologies! I'm not seeing what I'm doing wrong, or if it is a quirk of foreach loops it would be useful to know what and why. I was trying this out purely as an example to see how the loops work in php, so I just added them one after another in a file.

My code (based off an example in a book):

<?php

$p = array(
    'Copier' => "Numero Uno",
    'Inkjet' => "Numero Dos",
    'Laser' => "Numero Tres",
    'Photo' => "Numero Cuatro"
);

foreach ($p as $item => $desc) {
    echo "$item: $desc<br />";
}

echo "<br />";
echo "---";
echo "<br /><br />";

while (list($item2, $desc2) = each($p)) {
    echo "$item2: $desc2<br />";
}

With this code I get this output:

Copier: Numero Uno
Inkjet: Numero Dos
Laser: Numero Tres
Photo: Numero Cuatro

---

If I swap the foreach and while loops I get this (which is what I expect):

Copier: Numero Uno
Inkjet: Numero Dos
Laser: Numero Tres
Photo: Numero Cuatro

---

Copier: Numero Uno
Inkjet: Numero Dos
Laser: Numero Tres
Photo: Numero Cuatro

Because I've not been getting an output for the while if it runs after the foreach, I renamed item and desc just in case (hence why $item2, $desc2).

While writing this it occurred to me to make a new variable array from $p and try with that ($p2).

$p2 = $p;

while (list($item2, $desc2) = each($p2)) {
    echo "$item2: $desc2<br />";
}

This works. I also tried repeating the foreach loop again exactly the same (copy and pasted to where the while was) and that works.

Does the foreach somehow arrange the $p array in a way that the while doesn't understand? What is going on here? Is there a useful way to see what is going on under the hood in php?

7
  • @JayBlanchard oooh really? I haven't come across that yet. Is that just for foreach? I read on another post that foreach automatically sets the pointer to the first element in the array when it is being used (is this true?) which would explain why it works when duplicated. So while doesn't do this and doesn't need to be reset? Commented Sep 29, 2017 at 20:04
  • ah... comment disappeared. Commented Sep 29, 2017 at 20:04
  • 1
    each is deprecated as of PHP 7.2. If it's like other deprecated stuff in PHP, it won't actually be removed for a while, but just FYI. Commented Sep 29, 2017 at 20:13
  • Ah okay. Yeh the book I'm using is from 2009 so I expected some differences. There might be more than I expected... Commented Sep 29, 2017 at 20:15
  • 1
    @JayBlanchard sorry, I forgot ;) Commented Oct 6, 2017 at 20:43

1 Answer 1

2

After testing on PHP7 I could not replicate your problem, but if you're running on an earlier version of PHP you need to reset() the array pointer back to the beginning of the array:

$p = array(
    'Copier' => "Numero Uno",
    'Inkjet' => "Numero Dos",
    'Laser' => "Numero Tres",
    'Photo' => "Numero Cuatro"
);

foreach ($p as $item => $desc) {
    echo "$item: $desc<br />";
}

reset($p);

echo "<br />";
echo "---";
echo "<br /><br />";

while (list($item, $desc) = each($p)) {
    echo "$item: $desc<br />";
}

This produces (example):

Copier: Numero Uno
Inkjet: Numero Dos
Laser: Numero Tres
Photo: Numero Cuatro

---

Copier: Numero Uno
Inkjet: Numero Dos
Laser: Numero Tres
Photo: Numero Cuatro

Sign up to request clarification or add additional context in comments.

7 Comments

Works perfectly with reset! This is actually really useful to know just in case something else falls over when it doesn't access the pointer in the correct place.
on a side note, there's pretty much never any reason to use each() ... ever.
@WheatBeak can I ask why? It seems to me here that while each is a safer option to use than foreach for exactly the reason above.
I think the difference is because foreach doesn't move the internal array pointer any more in PHP 7. I think I remember reading that somewhere.
It's very old, slower than foreach, more to write, just really isn't useful in practice.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.