Frage zu Sichtbarkeit

unclejoe

Grünschnabel
Hallo, vorab möchte ich mich für die vielleicht triviale Frage entschuldigen, aber ich verstehe den Zusammenhang nicht.
Warum kann man $var zurück geben? Ich dachte, $var wäre nur innerhalb for-Schleife sichtbar/gültig wo diese auch deklariert wird.
Hätte $var vor der For-Schleife gestanden, könnte ich es nachvollziehen.

Code:
<?php

function test($anzahl) 
{
	for ($i = 0;$i<$anzahl;$i++)
	{
  		$var[] = $i;
	}
	return $var;
}

print_r (test(20));

?>

Wo ist mein Denkfehler?

Danke.
 
Zuletzt bearbeitet:
Hi und Willkommen bei tutorials.de,

eine der Eigenheiten von PHP...nicht wirklich dokumentiert (zumindest nicht da, wo es sein sollte),
und falls man schon andere Sprachen kennt einfach unlogisch.

Wirkliche Scopegrenzen sind nur Funktionen usw.
if, while, for ... oder einfach in {}-Block wirken sich in PHP nicht so aus.
 
Die Antwort ist vermutlich ganz einfach: PHP hat kein Konzept von beziehungsweise keine Syntax für Deklarationen im „lokalen“ Scope (und PHP erzwingt auch keine Initialisierung). Das macht untergeordnete Scope-Geschichten schwierig.

PHP:
$c = 0; // Das hier ist viel mehr eine Zuweisung als eine Deklaration
$c = 1; // Denn das hier ist definitiv keine Deklaration
{
    $c = 2; // Hier kann kein inneres $c deklariert werden, es gibt keine Syntax dafür
}


        // <- Auch hier fehlt keine Deklaration von $d, denn das Konzept existiert nicht
{
    $d = 1; // Das hier kann keine innere Variable sein, denn dazu müsste ich die
            // von einer äußeren Variablen unterscheidbar deklarieren können
}

Man kann sich das theoretisch auch so denken, was vielleicht ganz anschaulich ist:

PHP:
# "$" ist ein Mapping von Keys zu Inhalten und als Symbol immer im höchsten Scope "deklariert"

${'c'} = 0;
${'c'} = 1;
{
    ${'c'} = 2;
}


{
    ${'d'} = 1;
}

Ganz konkret:

PHP:
function f()
{
    ${'c'} = 0;
    ${'c'} = 1;
    {
        ${'c'} = 2;
    }


    {
        ${'d'} = 1;
    }

    var_dump(get_defined_vars());
}

f();

// array(2) {
//   'c' =>
//   int(2)
//   'd' =>
//   int(1)
// }



Einwand: Funktionen und Methoden haben einen eigenen Geltungsbereich.

Ja, stimmt schon. Programmiersprachen sind eben Definitionssache. Zumindest als „Merkhilfe“ finde ich mein Argument aber dennoch hilfreich. In den angesprochenen Fällen existiert zumindest das global-Schlüsselwort.​

PHP verhält sich eigentlich aber sehr logisch.

PHP:
function test($anzahl) 
{
    for ($i = 0;$i<$anzahl;$i++)
    {
        $var[] = $i;
    }
    return $var;
}

Dieses Beispiel wirft bei passender Einstellung des Error-Reportings eine Notice bei $anzahl = 0, weil $var nie konkret initialisiert wurde.

Auch in PHP gehört es zum guten Stil, den Code so zu schreiben:

PHP:
function test($anzahl) 
{
    $var = array();

    for ($i = 0;$i<$anzahl;$i++)
    {
        $var[] = $i;
    }
    return $var;
}

Das bedeutet, dass die gesamte Sache eigentlich völlig akademisch ist.
 
So, endlich auch einmal wieder zurück im Geschäft. Muss mich aber doch wieder etwas in die Grundlagen einarbeiten. Deshalb anknüpfend hier die Frage:

Das (Pseudo-)Initalisieren von Variablen am Anfang von Dokumenten / Funktionen dient also ausschliesslich der besseren Lesbarkeit und ist demnach nichts weiter als "guter Stil". Richtig?
 
Je nachdem.
Guter Stil ist es sowieso.

Wenn du eine Variable nicht initialisierst und sie dann aber auslesen willst, bekommst du einen Notice-Warnung von PHP. Je nach Einstellung wird dir die ausgegeben oder nicht.

PHP:
<?php
echo 'Hallo ' . $a;
?>
Ergibt:
Code:
Notice:  Undefined variable: a in C:\xampp\htdocs\test\test3.php on line 2

Hallo
So ergibt sich keine Notice sondern nur ein 'Hallo'
PHP:
<?php
$a = NULL;
echo 'Hallo ' . $a;
?>
 
Man macht das auch, damit etwa Funktionsrückgaben immer den gleichen Datentyp haben.

PHP:
function test($anzahl) 
{
    $var = array();

    for ($i = 0;$i<$anzahl;$i++)
    {
        $var[] = $i;
    }
    return $var;
}

Das liefert so immer ein Array zurück.
 
PHP:
function test($anzahl) 
{
    for ($i = 0;$i<$anzahl;$i++)
    {
        $var[] = $i;
    }
    return $var;
}

Unter welchen umständen würde es denn kein Array zurückgeben?
Wenn das array nur einen Wert enthält?
 
Zuletzt bearbeitet:
Wenn $anzahl <= 0 ist. Also der Wert, den du an die Funktion übergibst. Dann wird der Code in der Schleife nie ausgeführt und $var nicht initialisiert, was bedeutet, dass die Funktion null zurückgibt. (Standardwert für unbelegte Variablen.)
 
Danke für die vielen Rückmeldungen.

Das Thema scheint ja doch interessant für viele zu sein. Hatte ich zuerst gar nicht gedacht und mich kaum getraut, die Frage zu stellen. ;-) Im Studium (schon über 5 Jahre her) hatte ich vorwiegend Java mit strikter Typisierung etc. - fand dies immer recht anstrengend und zuerst dadurch PHP ganz angenehm, aber der Teufel steckt ja bekanntlich im Detail. Habe nun wieder etwas mit Programmieren begonnen, kann ja nicht schaden. :)
 
Danke für die vielen Rückmeldungen.

Das Thema scheint ja doch interessant für viele zu sein. Hatte ich zuerst gar nicht gedacht und mich kaum getraut, die Frage zu stellen. ;-) Im Studium (schon über 5 Jahre her) hatte ich vorwiegend Java mit strikter Typisierung etc. - fand dies immer recht anstrengend und zuerst dadurch PHP ganz angenehm, aber der Teufel steckt ja bekanntlich im Detail. Habe nun wieder etwas mit Programmieren begonnen, kann ja nicht schaden. :)

Zumindest machen sich die Leute hier noch ein wenig Gedanken darüber, was sie da eigentlich bauen...im Gegensatz zu diesem "Meisterstück" xD

PHP:
  $verguetung=getconfigitem("verg_".$_GET[typ]."view_".$waehrung."");
  mysql_query("INSERT INTO `view_log` (`time`, `user`, `ip`, `seiten_id`,`referer`, `format`, `werbe_id`, `waehrung`) VALUES ('".time()."', '$user', '$_SERVER[REMOTE_ADDR]', '$_GET[sid]', '$_SERVER[HTTP_REFERER]', '$_GET[typ]', '$_GET[werbe_id]','$waehrung');") or die(mysql_error());
 
Zurück