<? foreach ($this->criteria as $key => $value): ?>
<li><?= $this->accommodationsLink($this->criteria, $key) ?></li>
<? endforeach ?>
This code give unexpected results, because only one link is visible. But there are two items in $this->criteria.
I explored the cause of the probleem. In the function accommodationsLink is another foreach loop that works on the same criteria object
foreach ($criteria as $key => $value) {
$params[$key] = $value;
}
$this->criteria and $criteria are the same object that implements the php Iterator interface. Is there a simple way to let this code work or are nested foreach loops not possible with php iterator interface?
Well, the second foreach is going to call $iterator->reset()
prior to running. So when the second foreach reaches the end of the iterator, the internal pointer is already at the end of the array...
It'd be like:
$it->reset();
while ($it->valid()) {
$it->reset();
while ($it->valid()) {
//do something
$it->next();
}
$it->next();
}
Buy the time it gets to the $it->next()
call in the outer loop, it's already invalid. So the next()
call will "fail", and $it->valid()
would return false.
It's not a problem with iterators, it's a problem with the logic you're using. If you really must nest loops, then clone
the iterator ($subit = clone $it
) in the inner loop so you don't disturb the pointer...
Edit: Example with cloning:
$it->reset();
while ($it->valid()) {
$bar = clone $it;
$bar->reset();
while ($bar->valid()) {
//do something
$bar->next();
}
$it->next();
}
Or, using foreach (which is semantically equivalent):
foreach ($it as $key => $value) {
$subit = clone $it;
foreach ($subit as $k => $v) {
//Do stuff
}
}
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