To answer your question , let us first take a quick look at the foreach docs
On each iteration, the value of the current element is assigned to
$value and the internal array pointer is advanced by one (so on the
next iteration, you'll be looking at the next element).
First let's step up your first question and let's take your second question.
What I cannot understand is that aren't line 2 and line 3 basically
the same?
Actually they are not the same, take those quick examples :
$array = ['a', 'a', 'a', 'a'];
foreach ($array as $key => $value) {
$value = 'b';
}
print_r($array);
// Output : Array ( [0] => a [1] => a [2] => a [3] => a )
while in the second case :
$array = ['a', 'a', 'a', 'a'];
foreach ($array as $key => $value) {
$array[$key] = 'b';
}
print_r($array);
// Output : Array ( [0] => b [1] => b [2] => b [3] => b )
so, it's totally clear that in your first case, you had modified some copy value or assigned value so to speak, and did not touched the actual value.
so we can say that -so to speak- foreach as php functions has it's own context, for example :
foreach ($array as $key => $value) {
// $value variable will be only visible here
// within the foreach context
}
echo $value; // will output Undefined variable
They are both changing the same item in the $collection array.
you can say -or assume- that you've passed a variable to foreach by value, so php -as mentioned in foreach docs- had modified a copy of your array element , not the actual value.
while in second example, you've modified the real value of the array $array
not just a copy of it.
in my examples context, to modify your array in the place, you will need to pass your variable to foreach by reference to be able to edit your array value directly , for example :
$array = ['a', 'a', 'a', 'a'];
foreach ($array as $key => &$value) {
// ^
$value = 'b';
}
print_r($array);
// Output : Array ( [0] => b [1] => b [2] => b [3] => b )
let's move to your other question :
If I remove the line $collection[$key]['column'], the forloop can
finish successfully.
this is happens because as mentioned above , you are passing your variable to foreach by value, so for each iteration over your 30,000
array there are three operations php will perform :-
1) copy every element of your array to another place in your memory
2) update this copied element
3) update your collection array
which i think takes more memory that your maximum memory limit.
so, as Christopher
mentioned in his comment, and as mentioned in foreach doc page :
In order to be able to directly modify array elements within the loop
precede $value with &. In that case the value will be assigned by
reference.
passing your value by reference may reduce the memory usage of your script.