Zugriff auf eine globale Variable in einer PHP-Funktion


81

Gemäß den meisten Bereichsregeln für Programmiersprachen kann ich auf Variablen zugreifen, die außerhalb der darin enthaltenen Funktionen definiert sind. Warum funktioniert dieser Code jedoch nicht?

<?php
    $data = 'My data';

    function menugen() {
        echo "[" . $data . "]";
    }

    menugen();
?>

Die Ausgabe ist [].


3
Behandle es nicht als global, sondern übergebe es als Argument an die Funktion
Mark Baker

2
Wo sagt das Handbuch solche Dinge?
Täuschung

Verwandte Lesung: PHP global in Funktionen
Jocelyn

Überprüfen Sie das zweite Beispiel auf dieser Seite: php.net/manual/en/language.variables.scope.php
Amin Gholibeigian

afaik können wir mit $ GLOBALS ['varname'] zugreifen, wobei der Index "varname" $ ​​varname außerhalb der Funktion ist. Tatsächlich können wir print_r ($ GLOBALS) verwenden, um alle globalen Variablen anzuzeigen.
Ahmad

Antworten:


160

Es funktioniert nicht, weil Sie deklarieren müssen, auf welche globalen Variablen Sie zugreifen:

$data = 'My data';

function menugen() {
    global $data; // <-- Add this line

    echo "[" . $data . "]";
}

menugen();

Ansonsten können Sie darauf zugreifen als $GLOBALS['data']. Siehe Variabler Bereich .

Auch wenn dies ein wenig vom Thema abweicht, würde ich vorschlagen, dass Sie die Verwendung von Globals überhaupt vermeiden und es vorziehen, als Parameter zu übergeben.


Danke, Sie haben Recht, aber sie haben diese Zeile im zweiten Beispiel des Handbuchs nicht verwendet: php.net/manual/en/language.variables.scope.php
Amin Gholibeigian

6
Tatsächlich war dieses zweite Beispiel da, um den Lesern zu zeigen, was sie nicht tun sollten:This script will not produce any output because the echo statement refers to a local version of the $a variable, and it has not been assigned a value within this scope.
Matteo Tassinari

2
Dang! Ich musste mich anmelden, um diese Antwort zu verbessern, nur weil ich gruselig das Scoping von PHP-Variablen vergessen habe.
Milche Patern

19

Sie können eine der folgenden Aktionen ausführen:

<?php
    $data = 'My data';

    function menugen() {
        global $data;
        echo "[" . $data . "]";
    }

    menugen();

Oder

<?php
    $data = 'My data';

    function menugen() {
        echo "[" . $GLOBALS['data'] . "]";
    }

    menugen();

Allerdings kann eine übermäßige Verwendung von Globals zu einem schlechten Code führen. Es ist normalerweise besser, das einzugeben, was Sie brauchen. Anstatt beispielsweise auf ein globales Datenbankobjekt zu verweisen, sollten Sie ein Handle an die Datenbank übergeben und darauf reagieren. Dies wird als Abhängigkeitsinjektion bezeichnet . Es erleichtert Ihnen das Leben erheblich, wenn Sie automatisierte Tests implementieren (was Sie sollten).


12

Es ist eine Frage des Umfangs. Kurz gesagt, globale Variablen sollten vermieden werden, um :

Sie müssen es entweder als Parameter übergeben:

$data = 'My data';

function menugen($data)
{
    echo $data;
}

Oder haben Sie es in einer Klasse und greifen Sie darauf zu

class MyClass
{
    private $data = "";

    function menugen()
    {
        echo this->data;
    }

}

Siehe auch die Antwort von @MatteoTassinari, da Sie sie als global markieren können, um darauf zuzugreifen. Globale Variablen sind jedoch im Allgemeinen nicht erforderlich. Daher ist es ratsam, Ihre Codierung zu überdenken.


und eine andere Möglichkeit besteht darin, das Schlüsselwort global zu verwenden (zugegeben, dies ist nicht die beste Methode).
Jocelyn

1
"Sollte" beantwortet die Frage nicht, und dies ist möglicherweise nicht in jedem Fall der beste Ansatz. Bei einfachen Skripten ist es umständlich, Parameter zu ändern und Klassen hinzuzufügen. Ähnlich wie bei JavaScript muss in PHP nicht alles objektorientiert sein und im Wazoo einen Namespace haben.
Beejor

@Beejor Da das OP eine Funktion hat, die aufgerufen wird menugen(), bedeutet dies, dass mehr als nur ein Menü generiert wird. Wie wäre es beispielsweise mit der Erweiterung dieses Menüs, um weitere Elemente aus einer anderen Quelle hinzuzufügen, und mit der Auswahl der aktuell ausgewählten Seite im Menü. Überall zufällige globale Variablen und Logik zu haben, schreit nach OOP-Design. Die Tatsache, dass PHP / JS nicht strukturiert werden muss, ist einer der Hauptgründe, warum Sie viel unordentlichen, klobigen Code finden. Es kann sehr gut gemacht werden, aber die Leute können sich keine Gedanken über die Wartbarkeit in der Zukunft machen.
Webnoob

ps Down Voting Die Antwort ist auch ein bisschen falsch. Die Antwort bietet eine Lösung für das Problem des OP, nur weil es Ihnen nicht gefällt, macht es nichts falsch.
Webnoob

1
@Beejor - Das Problem mit diesem Argument ist, dass die Leute denken, sie brauchen eine globale Variable, weil sie es nicht besser wissen und es nicht besser wissen, wenn es ihnen nicht gesagt wird.
Webnoob

10

Ein anderer Weg, es zu tun:

<?php

$data = 'My data';

$menugen = function() use ($data) {

    echo "[".$data."]";
};

$menugen();

UPDATE 2020-01-13: angefordert von Peter Mortensen

Ab PHP 5.3.0 unterstützen wir anonyme Funktionen, mit denen Schließungen erstellt werden können. Ein Abschluss kann auf die Variable zugreifen, die außerhalb ihres Bereichs erstellt wurde.

In diesem Beispiel kann auf den Abschluss zugegriffen werden, $datada er in der useKlausel deklariert wurde .


Dies war die einzige funktionierende Lösung in meinem Fall, bei der ich eine Funktion als Variable in einer anderen Funktion definiert hatte. Global hat dort nicht funktioniert.
Kar.ma

Eine Erklärung wäre angebracht. ZB, was macht dieses "Gebrauch" -Ding? In welchen PHP-Versionen wird dieses "Use" -Ding unterstützt? (Bitte antworten Sie, indem Sie Ihre Antwort bearbeiten , nicht hier in den Kommentaren (falls zutreffend). Vielen Dank im Voraus.)
Peter Mortensen

Ich weiß nicht, warum die genehmigten Ans keine Ausgabe auf der Wordpress-Admin-Plugin-Seite anzeigen, aber diese Ans funktioniert gut.
Naimur Hasan

3

Seit vielen Jahren verwende ich immer dieses Format:

<?php
    $data = "Hello";

    function sayHello(){
        echo $GLOBALS["data"];
    }

    sayHello();
?>

Ich finde es einfach und leicht zu folgen. Mit $ GLOBALS können Sie mit PHP auf eine globale Variable verweisen. Wenn Sie Dinge wie $ _SERVER, $ _POST usw. verwendet haben, haben Sie eine Referenz auf eine globale Variable, ohne es zu wissen.


Welcher? $GLOBAL(Text) oder $GLOBALS(Beispielcode)? (Bitte antworten Sie, indem Sie Ihre Antwort bearbeiten , nicht hier in den Kommentaren (
Peter Mortensen

Es ist $ GLOBALS, nicht $ GLOBAL. Es sollte ein "S" geben. Verweisen Sie dann Ihren Variablennamen wie einen Schlüssel auf ein assoziatives Array.
Psalmen Kalu

Bitte aktualisieren Sie Ihre Antwort, indem Sie sie bearbeiten (um die Bearbeitung zu starten , klicken Sie zwischen "Teilen" und "Markieren" auf " Bearbeiten " . Diese drei befinden sich links - links von "bearbeitet" und "beantwortet" nach der Antwort selbst, über diesem Kommentar und vor allem drei Kommentaren hier). Informationen in Kommentaren können jederzeit verschwinden. Dies ist kein Forum - Informationen können (und sollten) hier aktualisiert werden. Vielen Dank im Voraus.
Peter Mortensen

0

Sie müssen die Variable an die Funktion übergeben:

$data = 'My data';

function menugen($data)
{
    echo $data;
}

0
<?php

    $data = 'My data';

    $menugen = function() use ($data) {

        echo "[ $data ]";
    };

    $menugen();
?>

Sie können auch vereinfachen

echo "[" . $data . "]"

zu

echo "[$data]"

echo "[" . $data . "]"und echo "[ $data ]"sind nicht gleich (zwei zusätzliche Leerzeichen in der Ausgabe für letztere).
Peter Mortensen

-1

Wenn Sie möchten, können Sie die Funktion "Definieren" verwenden. Diese Funktion erstellt jedoch eine Konstante, die nach der Definition nicht mehr geändert werden kann.

<?php
    define("GREETING", "Welcome to W3Schools.com!");

    function myTest() {
        echo GREETING;
    }

    myTest();
?>

PHP-Konstanten


Dies definiert eine globale Konstante, keine Variable.
Beejor

3
Einmal definierte Konstanten können nicht mehr geändert werden.
Beejor
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.