Referenz: Was ist Variablenbereich, auf welche Variablen kann von wo aus zugegriffen werden und was sind “undefinierte Variablen”-Fehler?

Lesezeit: 10 Minuten

Referenz Was ist Variablenbereich auf welche Variablen kann von wo
verzeihen

Hinweis: Dies ist eine Referenzfrage zum Umgang mit dem Gültigkeitsbereich von Variablen in PHP. Bitte schließen Sie jede der vielen Fragen, die zu diesem Muster passen, als Duplikat von diesem.

Was ist “variabler Geltungsbereich” in PHP? Sind Variablen aus einer .php-Datei in einer anderen zugänglich? Warum bekomme ich manchmal “undefinierte Variable” Fehler?

Referenz Was ist Variablenbereich auf welche Variablen kann von wo
verzeihen

Was ist “variabler Geltungsbereich”?

Variablen haben einen begrenzten “Geltungsbereich” oder “Orte, von denen aus auf sie zugegriffen werden kann”. Nur weil du geschrieben hast $foo = 'bar'; Einmal irgendwo in Ihrer Bewerbung bedeutet nicht, dass Sie darauf verweisen können $foo von überall, überallhin, allerorts sonst in der Anwendung. Die Variable $foo hat einen bestimmten Bereich, in dem sie gültig ist, und nur Code im selben Bereich hat Zugriff auf die Variable.

Wie wird ein Geltungsbereich in PHP definiert?

Ganz einfach: PHP hat Funktionsumfang. Das ist die einzige Art von Bereichstrennzeichen, die es in PHP gibt. 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 von Funktionen. Das bedeutet, dass es in PHP einen speziellen Geltungsbereich gibt: den global Umfang. Jede außerhalb einer Funktion deklarierte Variable befindet sich innerhalb dieses globalen Gültigkeitsbereichs.

Beispiel:

<?php

$foo = 'bar';

function myFunc() {
    $baz = 42;
}

$foo ist in der global Umfang, $baz ist in einem lokal Umfang nach innen myFunc. Nur Code drinnen myFunc Zugriff hat $baz. Nur codieren außen myFunc Zugriff hat $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 tun nicht getrennt Umfang:

a.php

<?php

$foo = 'bar';

b.php

<?php

include 'a.php';

echo $foo;  // works!

Die gleichen Regeln gelten für included-Code gilt für alle anderen Codes: nur functions separater Geltungsbereich. Aus Gründen des Umfangs können Sie daran denken, Dateien wie Code zum Kopieren und Einfügen einzuschließen:

c.php

<?php

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

    echo $foo;  // works
}

myFunc();

echo $foo;  // doesn't work!

Im obigen Beispiel a.php war drinnen enthalten myFuncalle Variablen darin a.php haben nur lokalen Funktionsumfang. Nur weil sie erscheinen im globalen Geltungsbereich zu sein a.php bedeutet nicht unbedingt, dass dies der Fall ist, es hängt tatsächlich davon ab, in welchem ​​​​Kontext dieser Code enthalten / ausgeführt wird.

Was ist mit Funktionen innerhalb von Funktionen und Klassen?

Jedes neu function -Deklaration 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

Wozu ist Umfang gut?

Der Umgang mit Scoping-Problemen mag lästig erscheinen, aber Ein begrenzter Variablenbereich ist für das Schreiben komplexer Anwendungen unerlässlich! Wenn jede Variable, die Sie deklarieren, überall in Ihrer Anwendung verfügbar wäre, würden Sie alle Ihre Variablen durchlaufen, ohne wirklich nachzuverfolgen, was was ändert. Es gibt nur so viele vernünftige Namen, die Sie Ihren Variablen geben können, dass Sie wahrscheinlich die Variable “$name” an mehr als einer Stelle. Wenn Sie diesen eindeutigen Variablennamen nur einmal in Ihrer App haben könnten, müssten Sie auf wirklich komplizierte Benennungsschemata zurückgreifen, um sicherzustellen, dass Ihre Variablen eindeutig sind und Sie nicht die falsche Variable ändern das falsche Stück Code.

Beobachten:

function foo() {
    echo $bar;
}

Was würde die obige Funktion tun, wenn es keinen Bereich gäbe? Wo tut $bar komme aus? Welchen Zustand hat es? Ist es überhaupt initialisiert? Muss man jedes Mal nachschauen? Dies ist nicht wartbar. Was uns zu …

Bereichsgrenzen überschreiten

Der richtige Weg: Variablen ein- und ausgeben

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

Die Variable $bar kommt explizit als Funktionsargument in diesen Bereich. Wenn man sich diese Funktion ansieht, wird klar, woher die Werte stammen, mit denen sie arbeitet. Es dann explizit kehrt zurück ein Wert. Der Aufrufer hat die Gewissheit zu wissen, mit welchen Variablen die Funktion arbeiten wird und woher ihre Rückgabewerte kommen:

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

Erweiterung des Geltungsbereichs von Variablen auf anonyme Funktionen

$foo = 'bar';

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

$baz();

Die anonyme Funktion schließt explizit ein $foo aus seiner Umgebung. Beachten Sie, dass dies nicht dasselbe ist wie global Umfang.

Der falsche Weg: global

Wie bereits erwähnt, ist der globale Geltungsbereich etwas speziell, und Funktionen können explizit Variablen daraus importieren:

$foo = 'bar';

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

Diese Funktion verwendet und modifiziert die globale Variable $foo. Mach das nicht! (Es sei denn, Sie wissen wirklich, wirklich, wirklich, was Sie tun, und selbst dann: nicht!)

Alles, was der Aufrufer dieser Funktion sieht, ist Folgendes:

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

Es gibt keinen Hinweis darauf, dass diese Funktion welche hat Nebenwirkungen, aber es tut es. Dies wird sehr leicht zu einem Wirrwarr, da sich einige Funktionen ständig ändern und erfordern irgendein Weltstaat. Sie wollen Funktionen sein staatenlosdie nur auf ihre Eingaben reagieren und eine definierte Ausgabe zurückgeben, egal wie oft Sie sie aufrufen.

Sie sollten es so weit wie möglich vermeiden, den globalen Gültigkeitsbereich zu verwenden. Ganz sicher sollten Sie keine Variablen aus dem globalen Bereich in einen lokalen Bereich “ziehen”.

  • Du hast einfach nur gesagt der falsche Weg für globalalso teilen Sie uns bitte mit, wann wir es verwenden sollen global ? Und bitte erklären (ein bisschen) was ist static ..?

    Benutzer4920811

    28. Juni 2015 um 10:14 Uhr


  • @stack Es gibt keinen “richtigen” Weg für global. Es ist immer falsch. Das Übergeben von Funktionsparametern ist richtig. static ist im Handbuch gut erklärt und hat nicht viel mit Umfang zu tun. Kurz gesagt kann man es sich als eine “Scoped Global Variable” vorstellen. Ich erweitere ein wenig auf seine Verwendung hier kunststube.net/static.

    – verzeihen

    28. Juni 2015 um 12:15 Uhr


  • Mein einfacher Gedanke ist, wenn eine PHP-Variable wichtig genug ist, um einen globalen Status zu verdienen, verdient sie eine Spalte in einer Datenbank. Vielleicht ist es ein Overkill, aber es ist ein idiotensicherer Ansatz, der zu meinem mittelmäßigen Programmierwitz passt

    – Arthur Tarasov

    3. August 2017 um 8:22 Uhr

  • @Arthur Da gibt es so viel zu entpacken… ಠ_ಠ Das ist ganz sicher kein Ansatz, den ich unterstützen würde.

    – verzeihen

    3. August 2017 um 8:24 Uhr

  • @Teemu Nein, da dies explizit die Weitergabe konfigurierbarer Namen ist. Es kann führen jedoch zu seltsamen Nebenwirkungen und machen nur in bestimmten Situationen Sinn preg_matchwo Sie einen „primären“ und „sekundären“ Rückgabewert haben.

    – verzeihen

    29. Juni 2021 um 18:13 Uhr

Obwohl auf Variablen, die innerhalb des Gültigkeitsbereichs einer Funktion definiert sind, nicht von außen zugegriffen werden kann, bedeutet dies nicht, dass Sie ihre Werte nicht verwenden können, nachdem diese Funktion abgeschlossen ist. PHP hat eine bekannte static Schlüsselwort, das im objektorientierten PHP weit verbreitet ist, um statische Methoden und Eigenschaften zu definieren, aber das sollte man im Hinterkopf behalten static kann auch innerhalb von Funktionen verwendet werden, um statische Variablen zu definieren.

Was ist eine „statische Variable“?

Statische Variablen unterscheiden sich von gewöhnlichen Variablen, die im Gültigkeitsbereich der Funktion definiert sind, falls sie ihren Wert nicht verlieren, wenn die Programmausführung diesen Gültigkeitsbereich verlässt. Betrachten wir das folgende Beispiel für die Verwendung statischer Variablen:

function countSheep($num) {
 static $counter = 0;
 $counter += $num;
 echo "$counter sheep jumped over fence";
}

countSheep(1);
countSheep(2);
countSheep(3);

Ergebnis:

1 sheep jumped over fence
3 sheep jumped over fence
6 sheep jumped over fence

Hätten wir definiert $counter ohne static dann wäre jedes Mal der wiedergegebene Wert derselbe wie $num Parameter, der an die Funktion übergeben wird. Verwenden static ermöglicht es, diesen einfachen Zähler ohne zusätzliche Problemumgehung zu erstellen.

Anwendungsfälle für statische Variablen

  1. Zum Speichern von Werten zwischen aufeinander folgenden Funktionsaufrufen.
  2. Um Werte zwischen rekursiven Aufrufen zu speichern, wenn es keine Möglichkeit (oder keinen Zweck) gibt, sie als Parameter zu übergeben.
  3. Wert zwischenspeichern, der normalerweise besser einmal abgerufen werden kann. Beispiel: Ergebnis des Lesens einer unveränderlichen Datei auf dem Server.

Tricks

Statische Variable existiert nur in einem lokalen Funktionsbereich. Es kann nicht außerhalb der Funktion, in der es definiert wurde, darauf zugegriffen werden. Sie können also sicher sein, dass es seinen Wert bis zum nächsten Aufruf dieser Funktion unverändert behält.

Statische Variable darf nur als Skalar oder als Skalarausdruck (seit PHP 5.6) definiert werden. Ihm andere Werte zuzuweisen, führt zumindest zum Zeitpunkt der Erstellung dieses Artikels unweigerlich zum Scheitern. Trotzdem können Sie dies nur in der nächsten Zeile Ihres Codes tun:

function countSheep($num) {
  static $counter = 0;
  $counter += sqrt($num);//imagine we need to take root of our sheep each time
  echo "$counter sheep jumped over fence";
}

Ergebnis:

2 sheep jumped over fence
5 sheep jumped over fence
9 sheep jumped over fence

Die statische Funktion wird zwischen Methoden von Objekten derselben Klasse “geteilt”. Es ist leicht zu verstehen, wenn man sich das folgende Beispiel ansieht:

class SomeClass {
  public function foo() {
    static $x = 0;
    echo ++$x;
  }
}

$object1 = new SomeClass;
$object2 = new SomeClass;

$object1->foo(); // 1
$object2->foo(); // 2 oops, $object2 uses the same static $x as $object1
$object1->foo(); // 3 now $object1 increments $x
$object2->foo(); // 4 and now his twin brother

Dies funktioniert nur mit Objekten derselben Klasse. Wenn Objekte aus verschiedenen Klassen stammen (und sich sogar gegenseitig erweitern), ist das Verhalten statischer Variablen wie erwartet.

Ist die statische Variable die einzige Möglichkeit, Werte zwischen Aufrufen einer Funktion beizubehalten?

Eine andere Möglichkeit, Werte zwischen Funktionsaufrufen beizubehalten, ist die Verwendung von Closures. Closures wurden in PHP 5.3 eingeführt. Mit zwei Worten, sie ermöglichen es Ihnen, den Zugriff auf einen Satz von Variablen innerhalb eines Funktionsbereichs auf eine andere anonyme Funktion zu beschränken, die der einzige Weg ist, auf sie zuzugreifen. In Closure-Variablen zu sein, kann (mehr oder weniger erfolgreich) OOP-Konzepte wie „Klassenkonstanten“ (wenn sie per Wert übergeben wurden) oder „private Properties“ (wenn sie per Referenz übergeben wurden) in der strukturierten Programmierung imitieren.

Letzteres ermöglicht tatsächlich die Verwendung von Closures anstelle von statischen Variablen. Was verwendet wird, ist immer Sache des Entwicklers, aber es sollte erwähnt werden, dass statische Variablen definitiv nützlich sind, wenn man mit Rekursionen arbeitet, und es verdienen, von Entwicklern beachtet zu werden.

Ich werde keine vollständige Antwort auf die Frage posten, da die vorhandenen und die PHP-Handbuch machen einen tollen Job, das meiste davon zu erklären.

Aber ein Thema, das verfehlt wurde, war das von Superglobaleeinschließlich der allgemein verwendeten $_POST, $_GET, $_SESSIONusw. Diese Variablen sind Arrays, die immer verfügbar sind, in jedem Gültigkeitsbereich, ohne a global Erklärung.

Diese Funktion gibt beispielsweise den Namen des Benutzers aus, der das PHP-Skript ausführt. Die Variable steht der Funktion problemlos zur Verfügung.

<?php
function test() {
    echo $_ENV["user"];
}

Die allgemeine Regel „Globals sind schlecht“ wird in PHP typischerweise in „Globals sind schlecht, aber Superglobals sind in Ordnung“ geändert, solange man sie nicht missbraucht. (Alle diese Variablen sind beschreibbar, sodass sie verwendet werden könnten, um eine Abhängigkeitsinjektion zu vermeiden, wenn Sie wirklich schrecklich wären.)

Das Vorhandensein dieser Variablen ist nicht garantiert; Ein Administrator kann einige oder alle von ihnen mithilfe von deaktivieren variables_order Richtlinie in php.iniaber das ist kein übliches Verhalten.


Eine Liste aktueller Superglobals:

  • $GLOBALS – Alle globalen Variablen im aktuellen Skript
  • $_SERVER – Informationen zum Server und zur Ausführungsumgebung
  • $_GET – Werte, die in der Abfragezeichenfolge der URL übergeben werden, unabhängig von der für die Anforderung verwendeten HTTP-Methode
  • $_POST – Werte, die in einer HTTP-POST-Anfrage mit übergeben werden application/x-www-form-urlencoded oder multipart/form-data MIME-Typen
  • $_FILES – Dateien, die in einer HTTP-POST-Anforderung mit a übergeben werden multipart/form-data Mime Typ
  • $_COOKIE – Mit der aktuellen Anfrage übergebene Cookies
  • $_SESSION – Sitzungsvariablen, die intern von PHP gespeichert werden
  • $_REQUEST – Typischerweise eine Kombination aus $_GET und $_POSTaber manchmal $_COOKIES. Der Inhalt wird bestimmt durch die request_order Richtlinie in php.ini.
  • $_ENV – Die Umgebungsvariablen des aktuellen Skripts

994350cookie-checkReferenz: Was ist Variablenbereich, auf welche Variablen kann von wo aus zugegriffen werden und was sind “undefinierte Variablen”-Fehler?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy