Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP same name in foreach as outer scope causes overwrite

So I was making a form today and happened to give the name of a variable the same name as a later used name in a foreach loop. To my surprise, the foreach loop's declaration overwrote the previous declaration of the variable.

To me, this seems rather strange since I expected the scope of the as $value => $a to limit the scope of the two variables to the foreach loop.

This is what happens:

php > $a = 5;
php > $b = array(1,2,3);
php > foreach($b as $value => $a){ echo $a; };
123
php > echo $a;
3

This is what I expected:

php > $a = 5; //define a in outer scope
php > $b = array(1,2,3);
php > foreach($b as $value => $a){ echo $a; /* This $a should be the one from the foreach declaration */ }; 
123
php > echo $a; //expecting inner scope to have gone away and left me to get the outer scoped $a

The same thing happens if I use $a as the key of foreach loop, more terrifying was this gem:

php > $a = 5;
php > $b = array(1,2,3);
php > foreach($b as $a => $b){ var_dump($b); }
int(1)
int(2)
int(3)
php > var_dump($b) // => int(3)

which overwrote the $b array in place, yet still looped over it's members.

All in all it seems a bit quirky. My question, is asking where exactly would I find the documentation/manual that specifies that this behavior is expected?

like image 228
EdgeCaseBerg Avatar asked Nov 14 '13 17:11

EdgeCaseBerg


2 Answers

The scope in PHP is at global or function level, there is no block scope, see http://php.net/manual/en/language.variables.scope.php

like image 77
Matteo Tassinari Avatar answered Oct 15 '22 18:10

Matteo Tassinari


Only functions create a new scope. block scope formed by curly braces do not form a new one .In your example you are in the global scope.

like image 22
litechip Avatar answered Oct 15 '22 20:10

litechip