Geltungsbereich von Variablen (Scope)

Welche Geltungsbereiche bzw. Scopes es gibt und welche Auswirkungen das auf den Zugriff auf Variablen hat

1. Einleitung

Entsprechend des Namens wird als Geltungsbereich (Scope) einer Variablen derjenige Bereich bezeichnet, in dem diese „aktiv” sind. Außerhalb ihres Geltungsbereichs können Variablen nicht ausgelesen werden. In PHP werden Geltungsbereiche typischerweise durch Funktionen gebildet. Variablen, die im „Körper” einer Funktion (also dem Bereich zwischen den geschweiften Klammern) definiert werden, gelten auch nur in diesem Bereich. Mit Beendigung der Funktion werden die Variablen ihres Geltungsbereichs automatisch gelöscht.

2. Beispiel: Kein Zugriff auf Variablen aus anderem Geltungsbereich

Im nachfolgenden Beispiel wird eine Variable $x im globalen Geltungsbereich definiert. Es wird versucht, auf diese Variable über die Funktion test() zuzugreifen. Dieser Zugriff schlägt aber fehl, da die Variable außerhalb des Geltungsbereichs der Funktion liegt. Anschließend wird innerhalb einer if-Abfrage auf die Variable zugegriffen. Da besagte if-Abfrage im globalen Geltungsbereich liegt, gelingt dieser Zugriff.

PHP-Code
<?php
    error_reporting(E_ALL);
	$x = 'bla';
	
	function test() {
		var_dump($x);
	}

	test();

	if (true) {
		var_dump($x);
	}
?>

HTML-Code: Ausgabe
<br />
<b>Notice</b>:  Undefined variable: x in <b>...\test.php</b> on line <b>6</b><br />
NULL
string(3) "bla"


3. Beispiel: Variablen aus anderem Geltungsbereich können nicht überschrieben werden

Da jeder Geltungsbereich von den anderen getrennt ist, kann man ohne Bedenken Variablennamen mehrmals verwenden. Es ist nicht nötig, sich Sorgen um versehentliches Überschreiben zu machen. Im nächsten Beispiel etwa wird der Variablen $x sowohl im globalen Geltungsbereich als auch im Geltungsbereich der Funktion „test()” jeweils ein Wert zugewiesen. Nach Verlassen der Funktion „test()” geht die lokale $x-Variable verloren. Beim nächsten Zugriff auf $x im globalen Geltungsbereich enthält die Variable daher nach wie vor den erwarteten Wert 1 und nicht 1000, der ihr in der Funktion zugewiesen wurde.

PHP-Code
<?php
	error_reporting(E_ALL);
	$x = 1; // $x im globalen Geltungsbereich
	
	function test() {
		// innerhalb von test() wird eine lokale Version von $x definiert
		$x = 1000;
		var_dump($x);
	}

	test();
	var_dump($x); // Zugriff auf $x im globalen Geltungsbereich
?>

HTML-Code: Ausgabe
int(1000)
int(1)


4. Beispiel: Bei Verlassen des Geltungsbereichs gehen seine Variablen verloren

Wenn in einem Geltungsbereich eine Variable definiert wird und im nächsthöheren Geltungsbereich noch keine gleichnamige Variable existiert, dann geht der Wert der Variable trotzdem bei Verlassen des Geltungsbereichs verloren. Im Beispiel wird in der Funktion „test()” die Variable $a mit dem Wert 1000 definiert. Nach Verlassen der Funktion wird versucht, die Variable $a auszugeben. Das schlägt fehl, da mit Verlassen von „test()” auch $a verloren gegangen ist und im globalen Geltungsbereich keine Variable mit dem Namen „$a” existiert.

PHP-Code
<?php
	function test() {
		$a = 1000;
	}
	
	test();
	var_dump($a);
?>

HTML-Code: Ausgabe
<br />
<b>Notice</b>:  Undefined variable: a in <b>...\test.php</b> on line <b>7</b><br />
NULL


5. Beispiel: Zugriff auf Variablen des globalen Geltungsbereichs

Variablen, die im globalen Geltungsbereich liegen, können in einen lokalen Geltungsbereich „importiert” werden. Verwendet wird dafür entweder das Schlüsselwort „global” oder das Array „$GLOBALS”.

PHP-Code
<?php
	$a = 'abc';

	function test() {
		global $a; 	// Variable $a aus dem globalen Geltungsbereich gilt nun auch im
				// Geltungsbereich der Funktion test()
		var_dump($a);
	}
	
	test();
?>

HTML-Code: Ausgabe
string(3) "abc"


6. Beispiel: Auf superglobale Variablen hat man von überall Zugriff

Eine spezielle Kategorie von Variablen sind die superglobalen Variablen (Superglobals). Diese Variablen gelten überall, man kann also jederzeit auf sie zugreifen, unabhängig vom aktuellen Geltungsbereich. Beispiele für Superglobals sind etwa $_GET (Parameter aus der URL), $_POST (gewöhnlich Formulareingaben), $_SERVER (Umgebungsvariablen), $_COOKIE (Cookies des Besuchers) und $GLOBALS (im Skript definierte globale Variablen).

PHP-Code
<?php
	// ein Wert wird in der superglobalen Variable $_GET hinterlegt
	$_GET['test'] = 'beispiel';

	function test() {
		// Auch in einer Funktion kann ohne weiteres auf diesen Wert zugegriffen werden
		var_dump($_GET['test']);
	}
	
	test();
?>

HTML-Code: Ausgabe
string(8) "beispiel"


7. Beispiel: Verschachtelte Funktionen bilden getrennte Geltungsbereiche

Funktionen können ineinander verschachtelt definiert werden — ihre Geltungsbereiche werden dadurch aber nicht ebenfalls verschachtelt, sondern bleiben getrennt. Im nachfolgenden Beispiel wird innerhalb von test() die Funktion testSub() definiert. Von testSub() aus wird nun versucht, auf eine in test() definierte Variable ($y) zuzugreifen, was einen Fehler erzeugt. Anschließend wird der Wert von $y in test() ausgegeben.

PHP-Code
<?php
	error_reporting(E_ALL);
	
	function test() {
		$y = 'test';
		function testSub() {
			var_dump($y);
		}
		
		testSub();
		var_dump($y);
	}

	test();
?>

HTML-Code: Ausgabe
<br />
<b>Notice</b>:  Undefined variable: y in <b>...\test.php</b> on line <b>7</b><br />
NULL
string(4) "test"


8. Beispiel: if's und Schleifen bilden keine Geltungsbereiche

In vielen Programmiersprachen wird ein Geltungsbereich durch geschweifte Klammern eingeleitet und beendet. In PHP ist das nicht der Fall. Nur Funktionen bilden eigene Geltungsbereiche (abgesehen vom globalen Geltungsbereich). Dadurch gehen Variablen, die innerhalb von if-else-Statements oder Schleifen definiert werden, nicht mit deren Ende verloren, sondern gelten darüber hinaus.

PHP-Code
<?php
	// Beispiel für if-else
	if (true) {
		$a = 1000;
	}

	var_dump($a);


	// Beispiel für Schleifen
	$arr = array(10, 11, 12);
	foreach ($arr as $value) {
		$foo = 'bar';
		echo($value . ", ");
	}
	echo("\n");

	// diese Variablen aus foreach haben "ueberlebt":
	var_dump($foo);
	var_dump($value);
?>

HTML-Code: Ausgabe
int(1000)
10, 11, 12, 
string(3) "bar"
int(12)



Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0