given the following code
<?php
$a = array(1,2,3,4,5,6);
$c=0;
foreach($a as $v){
if($v==5&&$c==0){
$c=1;
reset($a);
}
var_dump($v);
}
How do I reset the pointer so it will print 1,2,3,4,5,1,2,3,4,5,6 ?
I know that in this case I can simply
<?php
$a = array(1,2,3,4,5,6);
$c=0;
for($i=0;$i<count($a);++$i){
$v = $a[$i];
if($v==5&&$c==0){
$c=1;
$i=-1; //because of the loop ++$i
}
var_dump($v);
}
But I have a much more complex piece of code and the solution is not as simple as rewrite the loop (not numeric keys).
Any PHP guru out there that can help me here ?
As @TheodoreR.Smith pointed out in the comments. list() = each() will not work for any PHP version >= 7.2. See:
How can I update code that uses the deprecated each() function?
As documented:
Note: When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset() before a foreach loop.
As foreach relies on the internal array pointer, changing it within the loop may lead to unexpected behavior.
http://php.net/manual/en/control-structures.foreach.php
Not sure what "unexpected behavior" is, as I've never tried this...but maybe safer to manually use each()...also more clear in your code.
reset($a);
while(list($key, $val) = each($a)) {
if($val==5&&$c==0){
$c=1;
reset($a);
}
var_dump($val);
}
Foreach Issues Explained
I thought I had seen before that you couldn't rely on the internal pointer in the foreach...but couldn't find it in the documentation this time...only "unexpected results". However, thanks to a commenter, I found the text that used to be in the foreach:
Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it."
http://php.net/manual/en/control-structures.foreach.php#114759
If you are a fan of OOP, you can use the ArrayIterator class.
It has the method rewind() which is the same as the reset() function.
$a=array(1,2,3,4,5,6);//or $a=range(1,6);
$i=new ArrayIterator($a);
$c=0;
foreach($i as $k=>$v)
{
if($v==5&&$c==0)
{
$c=1;
$i->rewind();
}
var_dump($v);
}
unset($i);//delete the iterator, to free memory
You can test it online on http://writecodeonline.com/php/ or on http://sandbox.onlinephpfunctions.com/
@KevinNelson's answer is the right way to go, but it won't be obvious for the untrained eye.
There's a problem with this code.
Due to the iteration, the number 1 won't be echoed the 2nd time around.
But I've got 2 franken-solutions!
Solution 1: jump over an ignorable element, using the method next()
$a=array(0,1,2,3,4,5,6);//or $a=range(0,6);
$i=new ArrayIterator($a);
$c=0;
$i->next();//jumps over the 1st element
foreach($i as $k=>$v)
{
if($v==5&&$c==0)
{
$c=1;
$i->rewind();
}
var_dump($v);
}
unset($i);
Solution 2: create an element with 'falsy' value (0, null, false, ''...) and ignore it inside the loop
$a=array(0,1,2,3,4,5,6);//or $a=range(0,6);
$i=new ArrayIterator($a);
$c=0;
foreach($i as $k=>$v)
{
if($v==5&&$c==0)
{
$c=1;
$i->rewind();
}
if($v)var_dump($v);
}
unset($i);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With