我可以不在PHP中的foreach后循环数组吗?

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?

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