Sky.NET (17.06.2014)
Thema: global benutzen = nicht gut?
-
17.06.2014, 09:07 #1
global benutzen = nicht gut?
Hallo!
Ich verwende in PHP für Dinge die man oft braucht globale Variablen. Ein Beispiel ist die Datenbank. Die wird beim starten einmal connected
Wenn ich dann in einer Funktion darauf zugreifen möchte muss ich $db ja wieder global machen da es eine globale Variable ist und ich sonst keinen Zugriff darauf habe.PHP-Code:$db = new Dbase();
$db->connect(...)
Als ich gestern etwas gesucht habe bin ich auf einen Forums Eintrag gestoßen wo jemand meinte, es wäre nicht gut global zu benutzen. Das sei unsauberer Code. Darauf hin habe ich recherchiert und gesehen, dass man als Alternative eine statische Klasse nehmen kann, also etwa soPHP-Code:function foo() {
global $db;
$data = $db->fetch_row('select ...');
}
So kann man über Dbase von überall auf die Instanz zugreifen ohne sie global machen zu müssen.PHP-Code:class Dbase {
private static $instance;
public function get() {
return static::$instance;
}
}
Es spart bei jedem Aufruf in einer Funktion eine Zeile Code also scheint es besser zu sein. Also scheint es mir doch so zu sein dass es generell besser ist statische Klassen anstatt global zu benutzen.PHP-Code:function foo() {
$data = Dbase->get()->fetch_row('select ...');
}
Dann frag ich mich aber wieso ich die Datenbank Klasse überhaupt instanzieren soll? Anstatt ein unnötiges Objekt anzulegen könnte ich doch einfach die ganze Klasse statisch machen:
Da ich noch unerfahren mit php bin habe ich mal geschaut wie es das große wordpress so macht, denn die müssen es ja wohl wissen. Überraschenderweise wird sogar auf wordpress.org keine meiner Ideen benutzt sondern es wird mit global gemachtPHP-Code:class Dbase {
public static function connect() { ... }
public static function fetch_row($sql) {...}
...
}

Class Reference/wpdb « WordPress CodexPHP-Code:global $wpdb;
$results = $wpdb->get_results( 'SELECT * FROM wp_options WHERE option_id = 1', OBJECT );
Habe ich also doch etwas übersehen und es gibt Gründe wieso man lieber eine Instanz benutzen sollte und dann überall mit global darauf zugreift? Ich bin verwirrt!
-
17.06.2014, 10:46 #2
AW: global benutzen = nicht gut?
Grundsätzlich gilt immer - nicht nur in PHP, sondern auch in jeder anderen Sprache, die objektorientiert ist/unterstützt - den Scope so klein wie möglich zu halten.
Das was du statische Klasse nennst ist ein Entwurfsmuster. Eins von vielen, die sich im Laufe der Zeit etabliert haben. Das vorliegende Pattern nennt sich Singleton. Dein kleiner Codeausschnitt zeigt ungefähr auch schon, wie ein Singleton aufgebaut ist. Meistens versieht der Entwickler es noch mit Lazy Initialization. In der get-Methode wird geprüft, ob bereits eine gültige Instanz vorliegt: Wenn ja, wird sie zurückgegeben; wenn nicht, wird sie erzeugt und dann zurückgegeben.
Wenn man ein Objekt überall im übrigen Code braucht, bietet sich das Singleton an. Es kann aber auch missbraucht werden, weil es eben dadurch so einfach ist, sich um das objektorientierte Design keine Gedanken machen zu müssen und einfach viel zu viel zum Singleton macht.
Kürzer bedeutet nicht besser. Allgemein rate ich dir, nicht alles so kurz wie möglich zu halten, wenn darunter die Lesbarkeit leidet. Du gewinnst keinen Preis dadurch, wenn du Funktionalität in 5 Zeilen zusammenquetscht und nach einem Monat nicht mehr weißt, was du dort getan hast. Wer leserlich programmiert und sich an gewisse Regeln hält, der spart sogar Tipparbeit bei den Kommentaren. Die sind dann meist sogar überflüssig.
Zitat von Jokuu
-
The Following User Says Thank You to Nuebel For This Useful Post:
-
17.06.2014, 11:48 #3
AW: global benutzen = nicht gut?
Das kann ich verstehen, versuche auch nicht alles auf teufel komm raus so kurz wie möglich zu machen. In dem Fall sehe ich aber effektiv keinen Unterschied außer dass ich das global eben jedes mal brauche. Wenn man Code kürzer machen kann obwohl er das gleiche macht und ohne dass er unlesbar wird halte ich das nicht für schlecht. Wo soll denn da die Lesbarkeit leiden wenn ich die Datenbankklasse statisch mache? Da ändert sich ja nichts, nur mache ich dann direkt Database::fetch_row anstatt Database::get->fetchRow.
Ich sehe da einfach keinen Vorteil Singleton zu nutzen: Es wird ein Objekt erzeugt auf das statisch zugegriffen wird. Also ist das Objekt doch nutzlos und belegt unnötig Speicher. Verstehe mich nicht falsch, ich will dadurch nicht sagen alle Objekte sind unnötig weil man sie doch einfach statisch machen kann
Ich habe in Java einen Chat also Server und Client programmiert. Da habe ich eine Klasse Chatter geschrieben und für jeden User eine Instanz dieser Klasse erstellt.
Für die Chatuser fand ich es sehr nützlich Objekte erstellen zu können. Da macht es Sinn. Ich wüsste gar nicht wie ich das unobjektorientiert (gibt es das Wort?
) machen sollte. Aber bei einer Datenbankklasse sehe ich keine Vorteile, die mir ein Objekt bringt. Hier könnte ich doch genau so gut die Klasse statisch machen. Ich sehe allgemein keinen Vorteil der objektorientierung, wenn nur eine Instanz gebraucht wird.
Falls es Gründe gibt die ich nicht kenne bitte ich um Aufklärung. Es geht mir wie gesagt nicht darum mit der "Das kann man doch sowieso alles statisch machen" Keule auf OOP einzuschlagen. Ich sehe hier einfach nur keinen Vorteil. Große Software wie Wordpress löst es aber trotzdem mit einem Objekt. Auch in vielen Tutorials wird ein Objekt erzeugt. Ich würde gerne verstehen was dabei gedacht wurde.
Den einzigen Vorteil den ich sehe ist, dass man durch mehrere Instanzen problemlos Verbindungen zu mehreren Datenbanken herstellen könnte. Das scheint mir aber ein theoretischer Vorteil zu sein der praktisch sogut wie nie gebraucht wird. Mir fällt kein sinnvoller Zweck ein wofür man in der Webprogrammierung mehrere Datenbanken gleichzeitig brauchen würde. Normal hat Scheint also ein sehr seltener Spezialfall zu sein den man wohl problemlos vernachlässigen kann.Meine Tochter neulich im Zoo in der Arktisabteilung: "Guck mal Papi, da sind Linuxe!"

-
17.06.2014, 12:30 #4
AW: global benutzen = nicht gut?
Ich hatte mich nicht speziell auf deinen Fall bezogen:
Zitat von Jokuu
Das Problem bei Sprachen wie PHP oder auch C++ ist, dass es möglich ist, sowohl prozedural als auch objektorientiert zu programmieren. Mischt man beide Paradigmen wird es noch schlimmer. Solltest du dich für die Objektorientierung in deinem Projekt entscheiden, dann sei bitte so konsequent, dass du es auch durchziehst. Wenn du später das Projekt erweitern willst, wirst du dankbar dafür sein. Oder auch, wenn du entscheiden solltest, mit einem Kumpel daran zusammen weiter zu arbeiten.
Zitat von Nuebel
Im Speziellen für Datenbankverbindungen, hat sich mit der neuen PHP-Version Einiges getan, meine ich. Bin da nicht ganz up-to-date, da ich mit PHP kaum etwas zu tun habe.
Ich finde es gut, dass du nach dem Sinn fragst und es nicht einfach machst, weil es so üblich ist. Da gibt es auch noch andere Fragen im Zusammenhang mit der Objektorientierung, z.B.: Welchen Sinn hat es, objektorientiert zu programmieren, wenn man nicht Gebrauch von Vererbung und Polymorphie macht?
Zitat von Jokuu
Eine mögliche Reaktion darauf wäre, sich Was-wäre-wenn-Fragen zu stellen. Was wäre, wenn ich meine Abfragen vorher noch bearbeiten möchte? Im Code überall nach dem Aufruf von $db->query zu suchen und davor Etwas einfügen? Mit guten Texteditoren sogar mit geringem Aufwand möglich, aber besser wäre es doch, an einer Stelle es zu tun: In der Datenbankklasse mit ggf. überschriebener query-Methode.
In der hobbymäßigen Programmierung darf das vielleicht vernachlässigt werden, aber schaden kann es nicht.
-
The Following User Says Thank You to Nuebel For This Useful Post:
Jokuu (24.06.2014)
-
24.06.2014, 21:46 #5
AW: global benutzen = nicht gut?
Vererbung habe ich mir auch schon angeschaut. Rein aus interesse habe ich meine Datenbankklasse auch versucht sehr flexibel aufzubauen. Ich habe eine Wrapper-Klasse, in der sich die Instanz der eigentlichen Db-Klasse befindet:
Diese läd beim initialiseren die jeweils verwendete Server-Version. Im Moment beispielsweise Mysqli. Diese wiederum liegt einem Interface zugrunde:PHP-Code:class Dbase{
private static $dbInstance;
public static function get(){
return static::$dbInstance;
}
public static function create($type){
...
}
}
So kann ich rein theoretisch meinen Datenbank-Server jederzeit auswechseln, in dem ich einfach eine entsprechende Klasse dafür schreibe die eben auf dem Interface aufbaut.PHP-Code:interface Database {
public function query($qString);
public function connect($databaseHost, $databasePort, $databaseUsername, $databasePassword, $databaseName);
[...]
}
Konsequent habe ich OOP nicht umgesetzt. Aber nicht aus nachlässigkeit sondern bewusst. Ich dachte mir einfach, dass es sinnvoll wäre Objekte nur da zu benutzen wo es Sinn macht. Wo es keinen macht habe ich einfach statische Funktionen erzeugt. Wobei diese dann immer zu einer Klasse gehören, also keine reinen Dateien die nur aus Funktionen bestehen wie
Sondern immer als statische Klasse und FunktionPHP-Code:function xy() { ... }
function abc() { ... }
Der Gedanke dabei war auch möglichst performant zu programmieren. OOP verursacht ja etwas overhead, daher fande ich es unsinnig Objekte zu erzeugen und damit Performance zu verschwenden wenn es (aus meiner Sicht zumindest) keinen Sinn macht.PHP-Code:class contentHelper {
public static function cleanContent($content) { ... }
}
Meine Tochter neulich im Zoo in der Arktisabteilung: "Guck mal Papi, da sind Linuxe!"

Ähnliche Themen
-
Counter-strike Global Offensive
Von Ricardo1337 im Forum Gaming AllgemeinAntworten: 1Letzter Beitrag: 18.12.2013, 07:39 -
Counter-Strike: Global Offensive
Von k i N Z u im Forum Gaming AllgemeinAntworten: 13Letzter Beitrag: 24.11.2011, 21:07
Diese Seite nutzt Cookies, um das Nutzererlebnis zu verbessern. Klicken Sie hier, um das Cookie-Tracking zu deaktivieren.
Zitieren