Frage zu superglobalen Variablen

Hallo zusammen,
an verschiedenen Stellen verbinde ich mich mit meiner Datenbank. Wenn ich die Website auf meine Domäne lade, dann ändern sich natürlich host, username etc. Damit ich nicht alle Stellen heraussuchen muss, bei denen eine Datenbankverbindung aufgebaut ist, dachte ich mir, die Zugangsdaten superglobal zu speichern.

Ich weiß nur nicht, welches superglobale Array ich nutzen soll? Ich habe jetzt $GLOBALS verwendet, doch ist das korrekt? Sollte ich lieber anders die Zugangsdaten global speichern?

Momentan steht in meinem Head folgendes:

[PHP]
$GLOBALS[‚sqlhost‘] = ‚localhost‘;
$GLOBALS[‚sqluser‘] = ‚aaa‘;
$GLOBALS[‚sqlpass‘] = ‚bbb‘;
$GLOBALS[‚sqldatabase‘] = ‚ccc‘;
[/PHP]

Würdet ihr das auch so machen oder wie schaut eine bessere Lösung aus?

Vielen Dank
lg, freakXHTML

ich würde auf globale variablen verzichten PHP6 unterstützt diese eh nicht mehr, definiere dir lieber Konstanten mit define(„SQLHOST“, ‚localhost‘); :wink:

//oh du meinst ja $GLOBALS die gehn schon noch aber $var1 global geht nicht mehr … sry mein fehler… nichts destrotrotz würde ich es über konstanten lösen

Was? Ich PHP6 gibt es keine superglobalen Arrays mehr?? Hä? Wie soll dann der ganze POST und GET Kram funktionieren?

Wenn ich Konstanten anlege, dann muss ich die aber auch überall in jeder Datei deklarieren, weil die nicht superglobal sind. Dann kann ich doch gleich alle Stellen, an denen eine Verbindung mit der Datenbank hergestellt wird, manuell bearbeiten.

Vielen Dank
lg, freakXHTML

Ist Register Globals nicht etwas anderes als $GLOBALS ?

Und freakXHTML: Natürlich wird es die ganzen superglobalen Arrays wie $_POST, $_GET usw. noch in PHP 6 geben.
Aber zu deiner Vorgehensweise. Ich würde die Daten lieber in einer seperaten Datei hineinschreiben und diese bei bedarf includen. Dann musst du auch nicht mit globalen Variablen arbeiten :slight_smile:

Ja, register globals wird entfernt, nicht superglobale Arrays.

Konstanten gelten für die ganze Applikation, sie sind also auch „superglobal“ wenn du so willst.
Globale Variablen solltest du vermeiden so gut es geht, im Normalfall klappt das auch ohne Probleme. Es ist schlechtes Design :wink: Denn so werden alle deine verschiedenen Komponenten an die Existenz dieser Variablen gebunden, was die Wiederverwendbarkeit drastisch verschlechtert :wink:

Es gibt aber auch Ausnahmen :slight_smile:
Ich programmiere zur zeit an einem Pluginsystem. Und da muss ich auf eine Variable in allen Klassne zugreifen können. Und zwar zum Schreiben. Aber in diesem Fall währen Konstanten bzw meine oben genannte Methode wohl eher angemessen.

Dann würde ich ein Objekt definieren, das du über die Plugins hinweg teilst. (Ist jetzt natrürlich schwierig zu beurteilen, ohne deine genauen Zeile zu kennen) :slight_smile:

Bei mir habe ich dafür das JavaScript-Scope Konzept auf PHP portiert. Ich habe einen Variablen-Context, von dem kann ich Subcontexts erzeugen, die referenzieren dann jeweils ihren Parentscope. Setze ich eine Variable, so wird, wie in JavaScript, die Scopechain durchgegangen und es wird eine Variable mit diesem Namen gesucht. Wird sie in einem Scope gefunden, so wird diese überschrieben. Beim Lesen das gleiche. Wird sie nicht gefunden, wird sie standardmässig im aktiven Context eingetragen. Natürlich gibt es auch die Möglichkeit, eine lokale Variable zu forcieren.

@freakXHTML:

Du könntest die Konfigurationseinstellungen auch in einer externen Datei ablegen (zum Beispiel einer *.ini) und bei Bedarf in ein Config-Objekt laden. Dieses Objekt (bzw. Daten daraus) kannst du dann allen Stellen übergeben, die eine neue Verbindung zur Datenbank herstellen möchten.

(Vielleicht per parse_ini_file im Zusammenspiel mit dem hier: http://www.html.de/f8/punktnotation-multidimensionales-array-34117.html )

Die Variante mit den Konstanten ist aber wahrscheinlich einfacher. Globale Konstanten sind aber eigentlich eben auch „globale Zustände“ (siehe unten). Etwaige objektorientierte Ansätze machen im Prinzip nur dann Sinn, wenn deine Anwendung halbwegs objektorientiert programmiert ist und vielleicht dem FrontController-Layout (= alle Requests werden an eine index.php geschickt) folgt. Das ist wahrscheinlich nicht der Fall, weshalb ich mir da im Zweifel dann auch nicht zu sehr den Kopf zerbrechen würde. Die bereits angesprochenen Lösungen klappen ja auch.

@Gilles:

Das ist gewissermaßen die Diskussion Singleton (im Grunde ein globales Objekt) gegen Dependency Injection (~= Übergabe einer Klasseninstanz im Konstruktor). „Globale Zustände“ erschweren immer das Testen (und wahrscheinlich die Wiederverwendbarkeit, siehe auch Alshain) einer Klasse, da schwer zu überblicken ist, welche Abhängigkeiten eine Klasse tatsächlich hat.

Dazu gibt es in PHP-Foren alle naselang mehr oder wenige gute neue Threads mit durchaus differenzierten Meinungen:

Irgendwo darin verlinkt:

Auch wenn der allgemeine Tenor lautet „Singletons sind oft die schlechtere Lösung“, hält das übrigens große Frameworks (Zend) nicht davon ab, dieses Pattern (bzw. das Registry-Pattern) quasi an jeder Ecke zu verwenden. Theorie gegen Praxis. :wink:

@Alshain:

Hast du dazu ein Beispiel? Ich kann mir gerade nicht vorstellen, wie du das genau meinst.

Heisst ich könnte mit Singleton in einer Klasse einen Wert in dem Objekt setzen und könnte genau das Objekt welches auch die gleichen Werte hat in einer anderen Klasse wieder aufrufen? (Habs gesehne mit getInstance). Das funktioniert echt? Grade keine Möglichkeit zu testen ^^ Wenn ja wäre das eine echt coole Sache.
Noch nie mit Singletons beschäftigt

Ja, genau. Das Grundmuster für ein Singleton wird etwa hier vorgestellt: PHP: Patterns - Manual

(Die Methode, die dort „singleton“ heißt, wird üblicherweise „getInstance“ genannt.)

Hallo zusammen,
ich habe das Problem mit einer externen Datei gelöst. Darin deklariere die die nötigen Konstanten und erstelle gleich ein Objekt, das auf meine Datenbank zugreift! So funktioniert es sehr gut. Vielen Dank für die super Beratung.

Ich sehe globale Varianten als schlechten Stil an. Nur in sehr wenigen Fällen sind diese gut. Sie widersprechen dem kompletten Prinzip der Kapselung.

lg, freakXHTML

Wie wär’s zb. damit: Registry - php bar

Grüße

NewLord

Dann verstehst du was falsch, je nachdem, was man braucht, Logins, Rechte etc sollten im ganzen Script zur Verfügung stehen und nicht srändig neu abgefragt werden müssen. Permanente neue Abfrage sind Fehlerquellen und sicherheitskritisch.

Globale haben viele Vorteile. Ich prüfe die Rechte meiner User beim Login und setze sie in Sessions. Alle Prüfungen werden einmalig durchlaufen und die Scripte werden dadurch schneller.

Die Verwendung von register_global ist heute schlechter Stil, da Superglobale ($_SESSION, $_SERVER etc) eingerichtet wurden, die die Aufgabe besser, schneller und sicherer übernehmen.

Übrigens,
In Funktionen z.b. setze ich heute noch globale ein, da ich keine Lust habe, z.B ein Configfile immer neue einzulesen, wenn die Variablen $config schon alle definiert wurden.

[PHP]function bla()
{
global $config;
if($config[‚schreibwas‘] == „ja“) schreib_was();

}
[/PHP]

Ohne Rückgriff auf global sähe die Funktion dann eben so aus:

[php]function bla($config)
{
if($config[‚schreibwas‘] == „ja“) schreib_was();
}[/php]

$config wird also auch dann nicht immer wieder neu eingelesen, sondern lediglich sinnvoll weitergereicht.

Aus der Signatur der Funktion sind so zudem sämtliche Abhängigkeiten erkennbar. Dazu ist kein Blick in den Code mehr notwendig.

Wenn ich bla() wiederverwenden möchte, muss in einem weiteren Script keine globale Variable $config mehr existieren, ich muss bla() lediglich eine „Instanz“ von $config übergeben. (Das ist eine wesentlich weniger starke Voraussetzung.)

Wenn ich einen Test für bla() schreiben möchte, muss ich nicht „auf Verdacht“ ein gesamtes Anwendungsumfeld mit allen globalen Variablen bereitstellen, die theoretisch im zu testenden Code genutzt werden könnten, sondern brauche nur diejenigen Teile der Anwendung zu instanzi(i?)eren, die für die Funktion von bla() relevant sind. Welche das sind, kann ich relativ sauber an der Signatur ablesen.

Singletons, Registries (= Key/Value-Maps von Singletons) und per „global“ in den lokalen Scope gezogene Variablen sind bei dieser Betrachtungsweise mehr oder weniger dasselbe.

(Wobei an der Argumentation zugegeben noch mehr dranhängt und ich nicht sicher bin, ob sie sich überhaupt besonders gut auf prozedurale Programmierung übertragen lässt. Klickt zum Beispiel die php.de-Links in #8 durch für mehr Diskussion zu dem Thema.)

In PHP kann ich das nicht genau sagen, weil ich nicht genug Erfahrung habe. In C++ und ähnlichen Sprachen sollte man sich von globalen Variablen fern halten. Das ist Fakt!! Das gilt auch für die prozedurale Programmierung.

Bis bald
lg, freakXHTML

Globals gelten auch in PHP als Anti-Pattern, sonst würde es sowas wie Namespaces seit PHP 5.3 nicht geben.