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




function array (4)

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?


Answers

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.


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".


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 nach Abschluss dieser Funktion nicht verwenden können. PHP hat ein bekanntes static Schlüsselwort, das in objektorientiertem PHP weit verbreitet ist, um statische Methoden und Eigenschaften zu definieren, aber man sollte bedenken, dass auch static Funktionen innerhalb von Funktionen verwendet werden können, um statische Variablen zu definieren.

Was ist 'statische Variable'?

Die statische Variable unterscheidet sich von der normalen Variablen, die in dem Bereich der Funktion definiert ist, falls sie keinen Wert verliert, wenn die Programmausführung diesen Bereich verlässt. Betrachten wir das folgende Beispiel für die Verwendung von statischen 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

Wenn wir $counter ohne static dann wäre jeder wiederholte Wert gleich dem $num Parameter, der an die Funktion übergeben wurde. Wenn Sie static können Sie diesen einfachen Zähler ohne zusätzliche Problemumgehung erstellen.

Statische Variablen Use-Cases

  1. Speichern von Werten zwischen aufeinanderfolgenden Aufrufen für die Funktion.
  2. Um Werte zwischen rekursiven Aufrufen zu speichern, wenn es keinen Weg (oder keinen Zweck) gibt, sie als Parameter zu übergeben.
  3. Cache-Wert, der normalerweise besser einmal abgerufen werden kann. Zum Beispiel Ergebnis des Lesens einer unveränderlichen Datei auf dem Server.

Tricks

Statische Variable existiert nur in einem lokalen Funktionsumfang. Auf sie kann nicht außerhalb der Funktion zugegriffen werden, in der sie definiert wurde. Sie können also sicher sein, dass der Wert bis zum nächsten Aufruf dieser Funktion unverändert bleibt.

Statische Variable darf nur als skalarer oder skalarer Ausdruck definiert werden (seit PHP 5.6). Die Zuweisung anderer Werte führt unweigerlich zu einem Fehler mindestens in dem Moment, als dieser Artikel geschrieben wurde. Sie können dies jedoch 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, indem Sie das folgende Beispiel betrachten:

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 der gleichen Klasse. Wenn Objekte aus verschiedenen Klassen stammen (die sich sogar gegenseitig erweitern), verhält sich das Verhalten der statischen Variablen wie erwartet.

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

Eine andere Möglichkeit, Werte zwischen Funktionsaufrufen zu speichern, besteht darin, Closures zu verwenden. Closures wurden in PHP 5.3 eingeführt. Mit zwei Worten können Sie den Zugriff auf einige Variablen innerhalb eines Funktionsumfangs auf eine andere anonyme Funktion beschränken, die die einzige Möglichkeit darstellt, auf sie zuzugreifen. Wenn Sie in Closure-Variablen sind, können Sie (mehr oder weniger erfolgreich) OOP-Konzepte wie "Klassenkonstanten" (wenn sie als Wert übergeben wurden) oder "private Eigenschaften" (wenn sie als Referenz übergeben werden) im strukturierten Programmieren nachahmen.

Letztere erlaubt tatsächlich, anstelle von statischen Variablen Schließungen zu verwenden. Was zu verwenden ist, ist immer Sache des Entwicklers, um zu entscheiden, aber es sollte erwähnt werden, dass statische Variablen definitiv nützlich sind, wenn mit Rekursionen gearbeitet wird und es verdient, von Entwicklern bemerkt zu werden.


Parse-Fehler: Syntaxfehler, unerwarteter T_VARIABLE

Mögliches Szenario

Ich kann nicht finden, wo mein Code falsch gelaufen ist. Hier ist mein voller Fehler:

Parse-Fehler: Syntaxfehler, unerwarteter T_VARIABLE in Zeile x

Was ich versuche

$sql = 'SELECT * FROM dealer WHERE id="'$id.'"';

Antworten

Parse error: Ein Problem mit der Syntax Ihres Programms, z. B. das Lassen eines Semikolons am Ende einer Anweisung oder, wie im obigen Fall, das Fehlen der . Operator. Der Interpreter beendet das Programm, wenn ein Parse-Fehler auftritt.

In einfachen Worten ist dies ein Syntaxfehler, was bedeutet, dass etwas in Ihrem Code verhindert, dass es korrekt analysiert wird und daher ausgeführt wird.

Was Sie tun sollten, ist sorgfältig zu überprüfen, wo der Fehler für einfache Fehler liegt.

Diese Fehlermeldung bedeutet, dass der PHP-Interpreter in der Zeile x der Datei eine offene Klammer erwartet hat, aber stattdessen auf etwas namens T_VARIABLE . Diese T_VARIABLE Sache wird als token . Es ist die Art und Weise, wie der PHP-Interpreter verschiedene grundlegende Teile von Programmen ausdrückt. Wenn der Interpreter ein Programm einliest, übersetzt er das, was Sie geschrieben haben, in eine Liste von Token. Wo immer Sie eine Variable in Ihr Programm T_VARIABLE , gibt es in der Liste des Interpreters ein T_VARIABLE Token.

Gut zu lesen: Liste der Parser-Token

Stelle also sicher, dass du mindestens E_PARSE in deiner php.ini . Parse-Fehler sollten in Produktionsskripten nicht vorhanden sein.

Ich habe immer empfohlen, die folgende Aussage hinzuzufügen, während ich codiere:

error_reporting(E_ALL);

PHP Fehlerberichte

Es ist auch eine gute Idee, eine IDE zu verwenden, mit der Sie während der Eingabe Fehler parsen können. Sie können verwenden:

  1. NetBeans (schöne Schönheit, kostenlose Software) (meiner Meinung nach das Beste)
  2. PhpStorm (Onkel Gordon liebe das: P, bezahlter Plan, enthält proprietäre und freie Software)
  3. Eclipse (Schöne und das Biest, freie Software)

Verwandte Fragen:

  • Referenz: PHP Parse / Syntax Fehler; und wie man sie löst?




php scope