How does the foreach control structure behave when the array/collection being iterated is modified inside the loop?

First, I should point out that, in general, modifying the contents of a collection while iterating over it is considered a "bad thing" -- many languages will throw an exception if you try. PHP is not one of those languages, however Two things are relevant here for your question: First, when using arrays, PHP's foreach makes a copy of the array and iterates over that. In this case, you can safely modify the original array but your foreach won't see any of those changes.In your case that wouldn't work -- the new values you tack onto the end of $args won't come up in the foreach You can force PHP to use the original array by iterating over a reference to the array.

In this case, the internal behavior will become relevant. PHP keeps an internal pointer to the "next" array element. If you change the contents of an array element that 'foreach' has already seen, you will not see the changes.

If you change the contents of the array somewhere beyond the current element, you will see those changes. This should work for you, but I dunno if I'd trust it.

First, I should point out that, in general, modifying the contents of a collection while iterating over it is considered a "bad thing" -- many languages will throw an exception if you try. PHP is not one of those languages, however. Two things are relevant here for your question: First, when using arrays, PHP's foreach makes a copy of the array and iterates over that.In this case, you can safely modify the original array but your foreach won't see any of those changes.

In your case that wouldn't work -- the new values you tack onto the end of $args won't come up in the foreach. You can force PHP to use the original array by iterating over a reference to the array.In this case, the internal behavior will become relevant. PHP keeps an internal pointer to the "next" array element.

If you change the contents of an array element that 'foreach' has already seen, you will not see the changes. If you change the contents of the array somewhere beyond the current element, you will see those changes. This should work for you, but I dunno if I'd trust it.

This is an awesome answer. I would upvote it twice if I could. If I had known PHP copies arrays before iterating over them, I would have always iterated over references of arrays.

Every day I hate PHP a little bit more. – Eduardo León May 3 at 20:27 Do the is_array and array_merge functions also accept arrays by value instead of by reference? – Eduardo León May 3 at 20:31 As I understand it, PHP references are just aliased names for the same thing, so the reference should behave exactly the same as the original.

Having a reference to an object just forces PHP to act on the original since all of the changes need to be visible to all of the references at once. – Michael Edenfield May 3 at 20:46 You are right. But I don't want that my machine spend valuable time needlessly copying arrays.

– Eduardo León May 3 at 20:53.

For and foreach are pretty interchangeable, but in this case, you cannot add elements to the args array and process them right away with the foreach, so your function will not function the same way if you use foreach. A couple things to point out about the code: 1) putting the count($args) inside the 2nd parameter of the for loop means it's processed every iteration through the loop, which if you have a really large array can be expensive. I would count the number of args before processing the loop, store it in a variable and use that in place of count($args) in the for arguments, then add 1 to the count every time you add a new element to the args array.

This would be faster and use less memory. 2) This could be cleaned up to use recursion through functions, which would do the same thing without multiple loops and would use slightly less code.

Loops are more efficient than recursion. – Eduardo León May 3 at 20:33 That is certainly the case, however, for multi-dimensional arrays, recursion would be a lot more desirable because it provides the ability to easily iterate through every dimension of the array. Although that could still be done inside a loop if done correctly, as a personal preference, I would go with recursion instead.

Even in the case of scripting vs. OOP, scripting is more efficient and with a lot of extra work, can do everything OOP does, but the benefits of OOP greatly outweigh any performance hit and OOP is so much cleaner and more elegant. – Francis May 10 at 23:51.

$nums = array(1, 2, 3, 4); $newNum = max($nums) + 1; foreach ($nums as $num) { echo $num; if ($newNum > 10) { break; } $nums = $newNum++; } print_r($nums); /* output 1234 Array ( 0 => 1 1 => 2 2 => 3 3 => 4 4 => 5 5 => 6 6 => 7 7 => 8 ) */ Using reference foreach ($nums as &$num): /* output 1234567 Array ( 0 => 1 1 => 2 2 => 3 3 => 4 4 => 5 5 => 6 6 => 7 7 => 8 8 => 9 9 => 10 ).

First, I should point out that, in general, modifying the contents of a collection while iterating over it is considered a "bad thing" -- many languages will throw an exception if you try. PHP is not one of those languages, however. First, when using arrays, PHP's foreach makes a copy of the array and iterates over that.

In this case, you can safely modify the original array but your foreach won't see any of those changes. In your case that wouldn't work -- the new values you tack onto the end of $args won't come up in the foreach. You can force PHP to use the original array by iterating over a reference to the array.

In this case, the internal behavior will become relevant. PHP keeps an internal pointer to the "next" array element. If you change the contents of an array element that 'foreach' has already seen, you will not see the changes.

If you change the contents of the array somewhere beyond the current element, you will see those changes. This should work for you, but I dunno if I'd trust it.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions