⬆️ ⬇️

Underwater stone in foreach ($ items as & $ item)

Many people like to write such constructions in one form or another, everyone came across:

foreach ($items as &$item) { $item += 2; } 


But not many people suspect the danger lurking here.

Consider an example.



Vasya Pupkin took an array, walked through it, increasing by two all the elements:

 $items = array( 'a' => 10, 'b' => 20, 'c' => 30, ); foreach ($items as &$item) { $item += 2; } print_r($items); 


I looked at the dump, saw that the problem was solved, and left satisfied:

 Array ( [a] => 12 [b] => 22 [c] => 32 ) 


After some time, Petrovich decided to supplement this section of code with another search, by adding below:

 $newitems = array( 'a' => 10, 'b' => 20, 'c' => 30, ); foreach ($newitems as $key=>$item) { $newitems[$key] += 5; } print_r($newitems); 


I looked that his task was also solved, and with a sense of accomplishment, he closed the file:

 Array ( [a] => 15 [b] => 25 [c] => 35 ) 


After some time, inexplicable bugs began to emerge. Why?

Let's make var_dump ($ items) at the end of the code:

 array(3) { ["a"]=> int(12) ["b"]=> int(22) ["c"]=> &int(30) } 


thirty! Vasya Pupkin swears he checked. Why was 32, and after the Petrovich code 30?



The reason lies in the ampersand. He reports that someone else refers to the marked data. As he left, Vasya did not clean up a temporary variable, which he used for searching ($ item). The variable was used with permission to change the source ("&"), which is also called "assignment by reference." He was sure that the variable would be used only inside the loop. Petrovich, using a variable with the same name, during his search, changed its value, and each time the place where this variable was stored changed. And it was stored in the same place where the last element of the Pupkin array.



Of course, in the case of the article is exaggerated. In practice, such links can be very complex, especially if the project is inexpensive, and insufficiently experienced and isolated web developers participate in it.

')

How can you turn around with it?



In conclusion, I will say that the bugs associated with links can be not only in foreach. And they were all once discussed. However, this case, judging by my experience, is so common in practice that it deserves special attention.

Source: https://habr.com/ru/post/136835/



All Articles