2013-11-14 14 views
8

So machte ich heute ein Formular und gab zufällig den Namen einer Variablen den gleichen Namen wie ein später verwendeter Name in einer foreach-Schleife. Zu meiner Überraschung hat die Erklärung der foreach-Schleife die vorherige Deklaration der Variablen überschrieben.PHP gleichen Namen in foreach als äußeren Bereich verursacht überschreiben

Für mich scheint dies ziemlich seltsam, da ich den Umfang der as $value => $a erwartet, um den Umfang der beiden Variablen auf die foreach Schleife zu begrenzen.

Dies ist, was passiert:

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

Dies ist, was ich erwartet hatte:

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 

Das gleiche passiert, wenn ich $a als Schlüssel von foreach Schleife verwenden, erschreckender war dieses Juwel:

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) 

die dieüberschrieben 0 Array an Ort und Stelle, aber immer noch über seine Mitglieder geloopt.

Alles in allem scheint es ein bisschen skurril. Meine Frage, fragt wo genau würde ich die Dokumentation finden, die angibt, dass dieses Verhalten erwartet wird?

+7

PHP ist auf der Funktionsebene. foreach() erstellt keinen neuen Bereich. Abgesehen davon wird es im Falle Ihrer zweiten $ b => $ b Version einen temporären "Alias" geben. Das ist eher ein Nebeneffekt von phps Internals, als dass ein neuer Bereich erstellt wird. –

+0

Scoping wird überhaupt nicht auf der Schleifenebene durchgeführt? – EdgeCaseBerg

+0

Nein. Es gibt 2 Bereiche in PHP. globale und lokale Funktion/Methode. –

Antwort

1

nur Funktionen erstellen Sie einen neuen Bereich sehen. Der durch geschweifte Klammern gebildete Blockbereich bildet keinen neuen Bereich. In Ihrem Beispiel befinden Sie sich im globalen Bereich.