[PHP] mysqli übergeben Globals/Singleton

Dieses Thema im Forum "Webentwicklung" wurde erstellt von Terrorbeat, 25. Mai 2011 .

Schlagworte:
  1. 25. Mai 2011
    mysqli übergeben Globals/Singleton

    HI

    Ich verstehe eine sache im OO nicht. Warum ist es so gehasst Globals im OO zu verwenden insbesondere wen man Variablen übergeben möchte? Ich habe das häufig gelesen und immer erfolgreich verhindert Globals zu verwenden doch bei mysqli wollte mir keine andere Lösung einfallen. Also ging ich ins Internet und lass etwas von Singleton. Aber wieso ist jetzt der zweite Lösungsweg (sofern ich diesen überhaupt richtig angewendet habe) der bessere wobei doch erstere deutlich kürzer ist.

    PHP:
    //Gehasst
    test ();

    $mysqli  = @new  mysqli ( DB_HOST DB_USER DB_PASSWORD DB_DATABASE );

    function 
    test () {
        
    $mysqli  $GLOBALS [ 'mysqli' ];
        
    var_dump ( $mysqli );
    }
    PHP:
    //als Lösung anerkannt
    test ();

    //MySqli Database connect als Singleton
    final class  gb_mysqli 
        
    // Anlegen der Instanz
        
    private static  $instance  NULL ;    
     
        
    // Diese statische Methode gibt die Instanz zurueck.
        
    public static function  getInstance () { 
           if (
    self :: $instance  ===  NULL ) {
               
    self :: $instance  = @new  mysqli ( DB_HOST DB_USER DB_PASSWORD DB_DATABASE );
           }
           return 
    self :: $instance ;
        }
        
        
    // Konstruktor private, damit die Klasse nur aus sich selbst heraus instanziiert werden kann.
        // Klonen per 'clone()' von außen verbieten.
        
    private function  __construct () {}
        private function 
    __clone () {}
    }

    function 
    test () {
        
    var_dump ( gb_mysqli :: getInstance ());
    }

     
  2. 25. Mai 2011
    AW: mysqli übergeben Globals/Singleton

    Ein wenig älter, aber relativ gut erklärt: gps10s blog - Why Global Variables in PHP is Bad Programming Practice

    Ich frage mich vielmehr, wenn man Global nicht nutzen sollte, warum wird es denn unterstützt? Und warum wird, nur auf Grund der angestrebten Ähnlichkeit zu anderen Sprachen, für die selbe Funktion mehrere Möglichkeiten gegeben (print, echo .. etc pp).

    Aber zum Global, siehe Link.

    Edit: Will mal murdocs Antwort lesen
     
  3. 25. Mai 2011
    AW: mysqli übergeben Globals/Singleton

    print und echo sind nicht die selben funktionen. print kann im gegensatz zu echo als audruck verwendet werden.

    PHP:
    ( $test1234  ===  true ) ? print  'hallo'  : print  'welt' ;
    sowas wird zwar in realen anwendungsfällen sogut wie nie der fall sein

    ansonsten sind print und echo identisch.

    ---------------------

    globale variablen:

    der hauptgrund warum man sie nicht verwenden sollte ist der, dass man nie wirklich sicher sein kann, dass eine variable wirklich global ist.

    PHP:
    $foo  1 // global


    function  print_foo () {
        global 
    $foo ;

        print 
    $foo ;
    }
    führt man die funktion aus sollte "1" ausgegeben werden.

    macht man es aber so:
    PHP:
    function  call_print_foo () {
        include 
    'print_foo.php' ;

        
    print_foo ();  // 1 (oder?)
    }
    gibt auch "1" aus?
    nein, denn die variable $foo in der datei ist nicht länger global, sondern nur in der funktion "call_print_foo" vorhanden.

    so entstehen schnell fehler und man kann sich auf die suche begeben.

    daher ist es ratsam auf klassen zurückzugreifen, denn diese sind im gegensatz zu variablen immer global bzw. können global referenziert werden (\foo\bar\Klasse).

    für globale variablen kann man auf eine "registry" zurückgreifen.
    signleton wird verwendet wenn du nur eine instanz der klasse erlauben willst.

    ob du nun mit Klasse::getInstance() oder mit Registry::get('klasse') arbeiten willst bleibt dir überlassen.
    (bei einer datenbank macht singleton aber keinen sinn)

    die verwendung von $GLOBALS ist auch nicht sehr ratsam.
    ich persönlich meide den globalen-scope, da dieser php gehört.
     
  4. 25. Mai 2011
    AW: mysqli übergeben Globals/Singleton

    Mit dem zweit letzten Absatz wiedersprichst du so gut wie jeder Anleitung im Internet samt php.net ich Zitiere:
     
  5. 25. Mai 2011
    AW: mysqli übergeben Globals/Singleton

    tja, leider trifft das nicht immer zu.

    fall #1:
    wenn du mysql in nem cluster betreibst und SELECT von UPDATE, INSERT und DELETE separiert an einen anderen server sendest brauchst du min. zwei verbindungen.

    fall #2:
    wenn du zwei separate datenbanken hast in der du zb. in der ersten ein cms installiert hast und in der zweiten deine musik-sammlung aber beides in der selben applikation benötigst, brauchst du auch zwei verbindungen.

    solche fälle finden sich oft in intranet anwendungen wieder.
    datenbank 1: applikation
    datenbank 2: kundendaten

    daher ist ein singleton bei datenbanken nicht sinnvoll.
    hier eignet sich ein registy-pattern besser, das kannst du ja in deiner datenbank-klasse direkt mit implementieren.

    PHP:
    class  Database  extends  PDO
    {
        protected static 
    $registry  = array(),
                         
    $config    = array();
                         
        protected function 
    __construct ( $dsn $user $pass )
        {
            
    parent :: __construct ( $dsn $user $pass );
        }

        public static function 
    get ( $alias )
        {
            if (!isset(
    self :: $registry [ $alias ]))
                
    self :: $registry [ $alias ] =  self :: connect ( $alias );
                
            return 
    self :: $registry [ $alias ];
        }
        
        public static function 
    set ( $alias $name $host $user $pass $port  null )
        {
            
    self :: $config [ $name ] = array(
                
    'name'  =>  $name ,
                
    'host'  =>  $host
                
    'user'  =>  $user
                
    'pass'  =>  $pass ,
                
    'port'  =>  $port );
        }   
        
        protected static function 
    connect ( $alias )
        {
            if (!isset(
    self :: $config [ $alias ]))
                throw new 
    Exception ( 'zugangsdaten für datenbank "'  $alias  '" nicht vorhanden' );
                
            
    $config  self :: $config [ $alias ];
            
    $dsn  'mysql:dbname='  $config [ 'name' ] .  ';host='  $config [ 'host' ];
            
            if (
    null  !==  $config [ 'port' ])
                
    $dsn  .=  ';port='  $config [ 'port' ];
            
            return new 
    self ( $dsn $config [ 'user' ],  $config [ 'pass' ]);
        }
    }
    PHP:
    Database :: set ( 'cms' 'dbname1' 'localhost' 'benutzer' 'passwort' );
    Database :: set ( 'kunden' 'dbname2' 'remote.host.com' 'benutzer' 'passwort' 1337 );

    $db1  Database :: get ( 'cms' );
    $db2  Database :: get ( 'kunden' );
    als beispiel mal eben in notepad erstellt.
     
  6. 26. Mai 2011
    AW: mysqli übergeben Globals/Singleton

    ansonsten sind print und echo identisch.
    Meine ich ja ..


    Mir geht ja fast immer einer ab, wenn murdoc mal eben kurz ein paar Zeilen hämmert, die dann besser sind als meine Class ..
     
  7. 26. Mai 2011
    AW: mysqli übergeben Globals/Singleton

    du sagst es.
    und dann noch so erklärt, dass man es auch versteht.

    @murdoc
    ich kann immer nur danke sagen, für deine hilfsbereitschaft und zeit die du dir nimmst.
    daumen hoch
     
  8. 26. Mai 2011
    AW: mysqli übergeben Globals/Singleton

    danke danke, da muss ich glatt das fenster hier aufmachen damit mein ego platz hat
     
  9. 26. Mai 2011
    AW: mysqli übergeben Globals/Singleton

    Hier ist noch ein kleiner Käfer drin.

    PHP:
    public static function  set ( $alias $name $host $user $pass $port  null )
        {
            
    self :: $config [ $alias ] = array(
                
    'name'  =>  $name ,
                
    'host'  =>  $host
                
    'user'  =>  $user
                
    'pass'  =>  $pass ,
                
    'port'  =>  $port );
        }  
    So ist es richtig.
     
  10. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.