1. #1
    Avatar von Jokuu
    Registriert seit
    08.03.2014
    Beiträge
    263
    Thanked 108 Times in 74 Posts

    Standard 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

    PHP-Code:
    $db = new Dbase();
    $db->connect(...) 
    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:
    function foo() {
        global 
    $db;
        
    $data $db->fetch_row('select ...');

    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 so

    PHP-Code:
    class Dbase {
        private static 
    $instance;
        public function 
    get() {
            return static::
    $instance;
        }

    So kann man über Dbase von überall auf die Instanz zugreifen ohne sie global machen zu müssen.

    PHP-Code:
    function foo() {
        
    $data Dbase->get()->fetch_row('select ...');

    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.

    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:

    PHP-Code:
    class Dbase {
        public static function 
    connect() { ... }
        public static function 
    fetch_row($sql) {...}
        ...

    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 gemacht

    PHP-Code:
    global $wpdb;
    $results $wpdb->get_results'SELECT * FROM wp_options WHERE option_id = 1'OBJECT ); 
    Class Reference/wpdb « WordPress Codex

    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!

  2. #2
    Avatar von Nuebel
    Registriert seit
    23.11.2013
    Beiträge
    446
    Thanked 361 Times in 236 Posts

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

    Zitat Zitat von Jokuu
    Es spart bei jedem Aufruf in einer Funktion eine Zeile Code also scheint es besser zu sein.
    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.

  3. The Following User Says Thank You to Nuebel For This Useful Post:

    Sky.NET (17.06.2014)

  4. #3
    Avatar von Jokuu
    Registriert seit
    08.03.2014
    Beiträge
    263
    Thanked 108 Times in 74 Posts

    Standard 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!"

  5. #4
    Avatar von Nuebel
    Registriert seit
    23.11.2013
    Beiträge
    446
    Thanked 361 Times in 236 Posts

    Standard AW: global benutzen = nicht gut?

    Zitat Zitat von Jokuu
    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 hatte mich nicht speziell auf deinen Fall bezogen:
    Zitat Zitat von Nuebel
    Allgemein rate ich dir, nicht alles so kurz wie möglich zu halten, wenn darunter die Lesbarkeit leidet.
    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.

    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.

    Zitat Zitat von Jokuu
    Ich sehe allgemein keinen Vorteil der objektorientierung, wenn nur eine Instanz gebraucht wird.
    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?
    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.

  6. The Following User Says Thank You to Nuebel For This Useful Post:

    Jokuu (24.06.2014)

  7. #5
    Avatar von Jokuu
    Registriert seit
    08.03.2014
    Beiträge
    263
    Thanked 108 Times in 74 Posts

    Standard 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:

    PHP-Code:
    class Dbase{
        private static 
    $dbInstance;

        public static function 
    get(){
            return static::
    $dbInstance;
        }

        public static function 
    create($type){
            ...
        }

    Diese läd beim initialiseren die jeweils verwendete Server-Version. Im Moment beispielsweise Mysqli. Diese wiederum liegt einem Interface zugrunde:

    PHP-Code:
    interface Database {
        public function 
    query($qString);
        public function 
    connect($databaseHost$databasePort$databaseUsername$databasePassword$databaseName);
        [...]

    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.

    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

    PHP-Code:
    function xy() { ... }
    function 
    abc() { ... } 
    Sondern immer als statische Klasse und Funktion

    PHP-Code:
    class contentHelper {
        public static function 
    cleanContent($content) { ... }

    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.
    Meine Tochter neulich im Zoo in der Arktisabteilung: "Guck mal Papi, da sind Linuxe!"

Ähnliche Themen

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