php - globale - Referenz: Was ist der Variablenumfang, welche Variablen sind von wo und was sind "undefined Variable"-Fehler?




php static variable (2)

Hinweis: Dies ist eine Referenzfrage zum Umgang mit dem Variablenumfang in PHP. Bitte schließe eine der vielen Fragen, die zu diesem Muster passen, als Duplikat von diesem.

Was ist "variabler Umfang" in PHP? Sind Variablen aus einer .php Datei in einem anderen zugänglich? Warum bekomme ich manchmal "undefined variable" Fehler?


Was ist "variabler Umfang"?

Variablen haben einen begrenzten "Umfang" oder "Orte, von denen sie zugänglich sind". Nur weil du $foo = 'bar'; hast $foo = 'bar'; einmal irgendwo in Ihrer Anwendung bedeutet nicht, dass Sie auf $foo von überall sonst in der Anwendung verweisen können. Die Variable $foo hat einen bestimmten Gültigkeitsbereich, in dem sie gültig ist, und nur Code im selben Bereich hat Zugriff auf die Variable.

Wie ist ein Bereich in PHP definiert?

Ganz einfach: PHP hat Funktionsumfang . Das ist die einzige Art von Bereichstrennzeichen, die in PHP existiert. Variablen innerhalb einer Funktion sind nur innerhalb dieser Funktion verfügbar. Variablen außerhalb von Funktionen sind überall außerhalb von Funktionen verfügbar, aber nicht innerhalb irgendeiner Funktion. Das bedeutet, dass es in PHP einen besonderen Bereich gibt: den globalen Bereich. Jede außerhalb einer Funktion deklarierte Variable gehört zu diesem globalen Bereich.

Beispiel:

<?php

$foo = 'bar';

function myFunc() {
    $baz = 42;
}

$foo befindet sich im globalen Bereich, $baz befindet sich in einem lokalen Bereich innerhalb von myFunc . Nur Code innerhalb von myFunc hat Zugriff auf $baz . Nur Code außerhalb von myFunc hat Zugriff auf $foo . Keiner hat Zugriff auf den anderen:

<?php

$foo = 'bar';

function myFunc() {
    $baz = 42;

    echo $foo;  // doesn't work
    echo $baz;  // works
}

echo $foo;  // works
echo $baz;  // doesn't work

Umfang und enthaltene Dateien

Dateigrenzen trennen keinen Bereich:

a.php

<?php

$foo = 'bar';

b.php

<?php

include 'a.php';

echo $foo;  // works!

Für d-Code gelten dieselben Regeln wie für jeden anderen Code: nur function s separater Bereich. Für den Zweck des Umfangs können Sie daran denken, Dateien wie Kopier- und Einfügen-Code einzubinden:

c.php

<?php

function myFunc() {
    include 'a.php';

    echo $foo;  // works
}

myFunc();

echo $foo;  // doesn't work!

Im obigen Beispiel wurde a.php in myFunc , alle Variablen in a.php nur einen lokalen Funktionsumfang. Nur weil sie in a.php im globalen Geltungsbereich zu sein a.php bedeutet dies nicht unbedingt, dass es tatsächlich darauf a.php , in welchem ​​Kontext der Code enthalten ist.

Was ist mit Funktionen innerhalb von Funktionen und Klassen?

Jede neue function führt einen neuen Bereich ein, so einfach ist das.

(anonyme) Funktionen innerhalb von Funktionen

function foo() {
    $foo = 'bar';

    $bar = function () {
        // no access to $foo
        $baz = 'baz';
    };

    // no access to $baz
}

Klassen

$foo = 'foo';

class Bar {

    public function baz() {
        // no access to $foo
        $baz = 'baz';
    }

}

// no access to $baz

Wofür ist der Umfang gut?

Der Umgang mit Scoping-Problemen mag ärgerlich erscheinen, aber ein begrenzter variabler Bereich ist für das Schreiben komplexer Anwendungen unerlässlich! Wenn jede von Ihnen deklarierte Variable von überall in Ihrer Anwendung verfügbar wäre, würden Sie alle Ihre Variablen überspringen, ohne wirklich nachvollziehen zu können, was sich ändert. Es gibt nur so viele sinnvolle Namen, die Sie Ihren Variablen geben können. Wahrscheinlich möchten Sie die Variable " $name " an mehreren Stellen verwenden. Wenn Sie diesen eindeutigen Variablennamen nur einmal in Ihrer App verwenden könnten, müssten Sie auf wirklich komplizierte Benennungsschemata zurückgreifen, um sicherzustellen, dass Ihre Variablen eindeutig sind und Sie nicht die falsche Variable aus dem falschen Codeabschnitt ändern.

Beobachten:

function foo() {
    echo $bar;
}

Wenn es keinen Spielraum gäbe, was würde die obige Funktion tun? Woher kommt $bar ? Welchen Zustand hat es? Ist es überhaupt initialisiert? Musst du das jedes Mal überprüfen? Dies ist nicht wartbar. Was bringt uns zu ...

Bereichsgrenzen überschreiten

Der richtige Weg: Variablen ein- und ausleiten

function foo($bar) {
    echo $bar;
    return 42;
}

Die Variable $bar kommt explizit als Funktionsargument in diesen Bereich. Betrachtet man diese Funktion, ist klar, woher die Werte stammen, mit denen sie arbeitet. Es gibt dann explizit einen Wert zurück. Der Aufrufer hat das Vertrauen, zu wissen, mit welchen Variablen die Funktion arbeitet und woher die Rückgabewerte kommen:

$baz   = 'baz';
$blarg = foo($baz);

Erweitern des Umfangs von Variablen in anonyme Funktionen

$foo = 'bar';

$baz = function () use ($foo) {
    echo $foo;
};

$baz();

Die anonyme Funktion enthält explizit $foo von dem umgebenden Bereich. Beachten Sie, dass dies nicht der gleiche ist wie der globale Gültigkeitsbereich.

Der falsche Weg: global

Wie bereits erwähnt, ist der globale Gültigkeitsbereich etwas Besonderes und Funktionen können explizit Variablen daraus importieren:

$foo = 'bar';

function baz() {
    global $foo;
    echo $foo;
    $foo = 'baz';
}

Diese Funktion verwendet und ändert die globale Variable $foo . Mach das nicht! (Es sei denn, du weißt wirklich wirklich, was du tust, und selbst dann tu es nicht!)

Der Aufrufer dieser Funktion sieht Folgendes:

baz(); // outputs "bar"
unset($foo);
baz(); // no output, WTF?!
baz(); // outputs "baz", WTF?!?!!

Es gibt keinen Hinweis darauf, dass diese Funktion irgendwelche Nebenwirkungen hat. Dies wird sehr leicht zu einem Wirrwarr, da einige Funktionen sich verändern und einen globalen Zustand erfordern . Sie möchten, dass Funktionen zustandslos sind , nur auf ihre Eingaben einwirken und definierte Ausgaben zurückgeben, wie oft Sie sie auch aufrufen.

Sie sollten es vermeiden, den globalen Bereich in irgendeiner Weise so weit wie möglich zu verwenden. Sicherlich sollten Sie Variablen nicht aus dem globalen in einen lokalen Bereich "ziehen".


Der Gültigkeitsbereich einer Variablen ist der Kontext, in dem sie definiert ist. Zum größten Teil haben alle PHP-Variablen nur einen einzigen Bereich. Dieser einzelne Bereich umfasst sowohl die enthaltenen als auch die erforderlichen Dateien. Beispielsweise:

<?php
$a = 1;
include 'b.inc';
?>

Hier wird die Variable $a innerhalb des mitgelieferten b.inc Skripts verfügbar sein. Innerhalb von benutzerdefinierten Funktionen wird jedoch ein lokaler Funktionsumfang eingeführt. Jede Variable, die in einer Funktion verwendet wird, ist standardmäßig auf den lokalen Funktionsumfang beschränkt. Beispielsweise:

<?php
$a = 1; /* global scope */ 

function test()
{ 
    echo $a; /* reference to local scope variable */ 
} 

test();
?>

Dieses Skript erzeugt keine Ausgabe, da sich die echo-Anweisung auf eine lokale Version der $ a-Variable bezieht und ihr in diesem Bereich kein Wert zugewiesen wurde. Sie werden feststellen, dass dies ein wenig anders als in der C-Sprache ist, da globale Variablen in C automatisch für Funktionen verfügbar sind, sofern sie nicht durch eine lokale Definition überschrieben werden. Dies kann einige Probleme verursachen, da Personen versehentlich eine globale Variable ändern können. In PHP müssen globale Variablen innerhalb einer Funktion global deklariert werden, wenn sie in dieser Funktion verwendet werden sollen.





scope