tobi85: mysql_* vs. mysqli_*

Hallo Zusammen,

momentan verwenden wir noch immer mysql statt mysqli. Lohnt sich denn der Umstieg enorm?

Andere Frage - bei mysqli wird immer eine CONNECTION verlangt. Muss ich also in jeder Funktion eine CONNECTION erneut aufbauen, oder kann man das irgendwie besser lösen?

$db = @mysqli_connect($dbserver, $dbuser, $dbpass);

$q = "SELECT * FROM tabelle1 LIMIT 10";
$res = mysqli_query($db,$q);

function test() {
   $db = @mysqli_connect($dbserver, $dbuser, $dbpass);
   $q = "SELECT * FROM tabelle2 LIMIT 10";

   $res = mysqli_query($db,$q);
}

test();
  1. Hallo

    momentan verwenden wir noch immer mysql statt mysqli. Lohnt sich denn der Umstieg enorm?

    Spätestens, wenn der Hoster PHP ausschließlich in der Version 7 betreibt, lohnt sich der Umstieg tatsächlich „enorm“. Die mysql-Schnittstelle steht dann nämlich nicht mehr zur Verfügung.

    Andere Frage - bei mysqli wird immer eine CONNECTION verlangt. Muss ich also in jeder Funktion eine CONNECTION erneut aufbauen, oder kann man das irgendwie besser lösen?

    Stelle die Verbindung einmal her und benutze die dabei erzeugte Verbindungskennung bei jeder folgenden Operation. Es gibt übrigens eine Ausnahme von der Pflicht, die Kennung in den Funktionen z benutzen. Nämlich den Fall eines Fehlerausgabe aus Anlass der Verbindungsaufnahme. Dann gibt es nämlich keine Kennung, weshalb die Funktionen mysqli_connect_error und mysqli_connect_errno ohne Kennungsangabe funktionieren (müssen).

    $db = @mysqli_connect($dbserver, $dbuser, $dbpass);
    
    function test() {
       $db = @mysqli_connect($dbserver, $dbuser, $dbpass);
       $q = "SELECT * FROM tabelle2 LIMIT 10";
    
       $res = mysqli_query($db,$q);
    }
    
    test();
    

    Öhhm, wie du Parameter an eine Funktion übergibst, ist dir vertraut?

    Tschö, Auge

    --
    Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
    Wolfgang Schneidewind *prust*
    1. Hallo, aber sorry. Kannst Du mal bitte ein Beispiel machen, wie ich den Verbindungskanal, welchen ich aufgebaut hatte, weiter nutze. In einer Funktion etc. müsste ich den Kanal immer wieder aufbauen - in jedem Fall hatte ich hier eine Fehlermeldung erhalten, dass etwas fehlen würde...

      $res = mysqli_query($q);

      1. Hallo

        Kannst Du mal bitte ein Beispiel machen, wie ich den Verbindungskanal, welchen ich aufgebaut hatte, weiter nutze. In einer Funktion etc. müsste ich den Kanal immer wieder aufbauen - in jedem Fall hatte ich hier eine Fehlermeldung erhalten, dass etwas fehlen würde...

        $res = mysqli_query($q);

        Hier fehlt ja auch die Verbindugnskennung, die, bis auf die im Vorposting genannt4en zwei Ausnahmen, immer als erster Parameter angegeben werden muss. Ausgehend von der Annahme, dass die Verbindungskennung in $db und der Query in $q steckt, sieht der Funktionsaufruf folgendermaßen aus.

        $res = mysqli_query($db, $q);
        

        Wie $db in die Funktion kommt? Als Parameter im Funktionsaufruf, wie bei den vorgefertigten Funktionen. Genau danach habe ich dich gefragt. Die Frage hast du leider nicht beantwortet.

        function test($kennung) {
            $q = "SELECT dies FROM jenem";
            $res = mysqli_query($kennung, $q);
            // mach etwas mit dem Ergebnis
        }
        
        $db = @mysqli_connect($dbserver, $dbuser, $dbpass, dbname);
        test($db);
        

        Tschö, Auge

        --
        Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
        Wolfgang Schneidewind *prust*
      2. In einer Funktion etc. müsste ich den Kanal immer wieder aufbauen - in jedem Fall hatte ich hier eine Fehlermeldung erhalten, dass etwas fehlen würde...

        Die $db_connect ist in einer Funktion nicht bekannt. Ebensowenig wie andere Variablen, die du ausserhalb der Funktion definiert hast.

        Du musst sie der Funktion bekannt machen:

        function tuWas() {
          global $db_connect, $andere_variable, ...;
          ...
        }
        

        Linuchs

        1. Hallo,

          Du musst sie der Funktion bekannt machen:

          function tuWas() {
            global $db_connect, $andere_variable, ...;
            ...
          }
          

          das will man nicht wirklich! Globale Variablen sind etwas, das man - von Ausnahmen abgesehen - normalerweise vermeidet. Eine Funktion sollte im Regelfall alles, was sie zum Arbeiten braucht, als Parameter bekommen. Wenn das eine größere Menge Daten ist, bietet sich ein Array oder ein Objekt an.

          So long,
           Martin

          --
          Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
          - Douglas Adams, The Hitchhiker's Guide To The Galaxy
        2. Hallo

          Die $db_connect ist in einer Funktion nicht bekannt. Ebensowenig wie andere Variablen, die du ausserhalb der Funktion definiert hast.

          Du musst sie der Funktion bekannt machen:

          function tuWas() {
            global $db_connect, $andere_variable, ...;
          }
          

          Aber bitte nicht so. Wozu ist wohl das Klammerpaar da, wenn nicht, um Parameter aufzunehmen?

          function tuWas($db_connect, $andere_variable, $schalter = false) {
          }
          

          Tschö, Auge

          --
          Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
          Wolfgang Schneidewind *prust*
          1. Hallo, aber sorry - jetzt bin ich nicht weiter. Wie bekomme ich meine CONNECTION in die Funktion, ohne dass ich diese permanent neu aufrufen muss, oder umständlich übergeben...

            
            
            $db = @mysqli_connect($dbserver, $dbuser, $dbpass);
            global $db;
            mysqli_select_db($db,$dbname);
            
            
            function test() {
            $q = "SELECT * FROM artikel LIMIT 10";
            $res = mysqli_query($db,$q);
            }
            
            
            
            1. Hallo

              Hallo, aber sorry - jetzt bin ich nicht weiter.

              Liest du, was dir geschrieben wird?

              Wie bekomme ich meine CONNECTION in die Funktion, ohne dass ich diese permanent neu aufrufen muss, oder umständlich übergeben...

              Entschuldige bitte, genau das wurde dir mittlerweile mehrfach (mit unterschiedlich geeigneten Wegen) erklärt. Übergebe die Variable, in der der Wert der Verbindungskennung aufbewahrt wird, an deine Funktion. Wie das gemacht wird, haben wir dir in mehreren Codebeispielen gezeigt.

              Wenn du diese nicht verstehst, frage bitte explizit zu den unklaren Punkten nach. Mit „ich bin nicht weiter“ kommst du hier – zumindest bei mir – nicht weiter.

              Tschö, Auge

              --
              Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
              Wolfgang Schneidewind *prust*
              1. Hallo,

                ich verstehe schon, wie Du es meinst. Nach deinem Beispiel müsste es wie folgt gehen, aber ich möchte diese Übergabe in der Funktion vermeiden. Du meinst es wohl wie folgt...

                
                function testtest($db) {
                $q = "SELECT * FROM artikel LIMIT 10";
                $res = mysql_query($q);
                }
                
                $db = @mysqli_connect($dbserver, $dbuser, $dbpass);
                
                testtest($db);
                
                1. Hallo tobi85,

                  aber ich möchte diese Übergabe in der Funktion vermeiden.

                  Warum?

                  Bis demnächst
                  Matthias

                  --
                  Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
                2. Hi,

                  ich verstehe schon, wie Du es meinst.

                  wirklich?

                  Nach deinem Beispiel müsste es wie folgt gehen, aber ich möchte diese Übergabe in der Funktion vermeiden.

                  Warum? Das ist unter anderem einer der größten Nutzeffekte von Funktionen.

                  function testtest($db) {
                  $q = "SELECT * FROM artikel LIMIT 10";
                  $res = mysql_query($q);
                  // NEIN! Du meintest wohl: $res = mysqli_query($db, $q);
                  // Außerdem hast du vergessen, dein $res auch an die übergeordnete Funktion zurückzugeben.
                  }
                  
                  $db = @mysqli_connect($dbserver, $dbuser, $dbpass);
                  
                  testtest($db);
                  

                  Nochmal: Eine Funktion ist ein Stückchen in sich abgeschlossener, gekapselter Code, der eine ganz bestimmte Aufgabe erledigt. Dazu bekommt er üblicherweise ein oder mehrere Aufrufparameter, und liefert ein Ergebnis zurück (return). In PHP (und ein paar anderen Sprachen) können Aufrufparameter optional sein, d.h. sie sind zwar im Funktionskopf definiert, können aber beim Aufruf je nach Situation auch weggelassen werden.

                  BEISPIEL:

                  function average(a, b, geo=false)
                   { if (isset(geo) && geo)         // wenn der Parameter geo angegeben wurde und true ist ...
                        av = sqrt(a*b);             // berechne den geometrischen Mittelwert
                     else
                        av = (a+b)/2;               // andernfalls den arithmetischen Mittelwert
                  
                     return (av);                   // und liefere den berechneten Wert als Ergebnis
                   }
                  
                  echo average(12, 15);             // optionaler Parameter fehlt, wird als false angenommen
                                                    // Ausgabe: 13.5
                  echo average(32, 128, true);      // dritter Parameter ist angegeben und true
                                                    // Ausgabe: 64
                  

                  DISCLAIMER: Normalerweise hätte ich anstatt der if-Fallunterscheidung den ternären Operator verwendet. Aber hier habe ich aus didaktischen Gründen ausnahmsweise die Langform gewählt.

                  Es gibt ab und zu Sonderfälle - Funktionen, die auch ohne Aufrufparameter etwas Sinnvolles tun, oder Funktionen, die kein Ergebnis liefern, weil sie ihre Aufgabe anderweitig abfrühstücken.

                  Und was ist daran nun so kompliziert, dass du dich so dagegen sträubst?

                  So long,
                   Martin

                  --
                  Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
                  - Douglas Adams, The Hitchhiker's Guide To The Galaxy
                3. Hallo

                  ich verstehe schon, wie Du es meinst. Nach deinem Beispiel müsste es wie folgt gehen, aber ich möchte diese Übergabe in der Funktion vermeiden.

                  Du willst in einer Funktion einen Wert „von draußen“ benutzen. Entweder du übergibst diesen Wert an die Funktion – mit welcher Methode auch immer – oder du lässt das mit der Funktion. Ganz einfach.

                  Tschö, Auge

                  --
                  Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
                  Wolfgang Schneidewind *prust*
                4. aber ich möchte diese Übergabe in der Funktion vermeiden.

                  Das willst Du nicht mehr wenn Du darüber nachgedacht hast, wie genial diese Isolierung ist und wie besch...eiden das früher mal in BASIC war, wo es diese Isolierung nicht gab.

                  Da hatte man es nämlich am Hals, die Variablenliste ständig zu verwalten und zu schauen, welche man schon benutzt - Das war eine nie versiegende Quelle äußerst schwer zu findender logischer Fehler welcher auch dazu beitrugen, dass BASIC sehr schnell von vielen als "völlig unbrauchbar" angesehen wurde.

                  Schau Dir an, was das hier macht:

                  <?php
                  for ( $i=1; $i<3; $i++ ) {
                      echo 'außerhalb $i: ', $i, "\n"; 
                      tu_was($i);
                  }
                  echo 'außerhalb $i: ', $i, "\n"; 
                  
                  function tu_was($in) {
                     for ( $i=11; $i<13; $i++ ) {
                         echo 'innerhalb $in: ', $in, ' | $i: ', $i, "\n";
                     }
                  }
                  

                  Ausgabe:

                  außerhalb $i: 1
                  innerhalb $in: 1 | $i: 11
                  innerhalb $in: 1 | $i: 12
                  außerhalb $i: 2
                  innerhalb $in: 2 | $i: 11
                  innerhalb $in: 2 | $i: 12
                  außerhalb $i: 3
                  
                  1. Hallo Zusammen,

                    ich habe nun den Abruf mal geändert und bekomme nun folgende Fehlermeldung. Aber warum - ist doch eigentlich alles richtig.

                    Fatal error: Call to undefined method mysqli::fetch_assoc() in

                    $mysqli = new mysqli($dbserver,$dbuser,$dbpass,$dbname);
                    $mysqli->query($q);
                    
                    while ($row = $mysqli->fetch_assoc()) {
                    }
                    
                    1. Naja...

                      $mysqli = new mysqli($dbserver,$dbuser,$dbpass,$dbname);
                      $mysqli->query($q);
                      while ($row = $mysqli->fetch_assoc()) {
                      }
                      

                      muss falsch sein:

                      Fatal error: Call to undefined method mysqli::fetch_assoc() in

                      denn Du musst zwischen dem Verbingungsobjekt und dem mit dem Resultat der Abfrage unterscheiden. Das hast Du nicht getan. Genauer gesagt hast Du es nicht mal gespeichert, sondern in den Müll gekippt. Dein Verbindungsobjekt hat also schon per Definition nicht die für das Resultat-Objekt gültige Methode "fetch_assoc".

                      $mysqli = new mysqli($dbserver,$dbuser,$dbpass,$dbname);
                      $result = $mysqli->query($q);
                      while ( $row = $result->fetch_assoc() ) {
                         #...
                      }
                      

                      Ich sehe auch keine Prüfungen auf Fehler. Dabei erklärt das PHP-Handbuch diese und hat wunderschöne Beispiele.

                      1. OK Danke! Aber dann mal noch doof gefragt - was ist der Unterschied von

                        $res->fetch_array()

                        mysqli_fetch_array($res)

                        oder ist egal was man verwendet?

                        1. Hallo

                          Aber dann mal noch doof gefragt - was ist der Unterschied von

                          $res->fetch_array()

                          mysqli_fetch_array($res)

                          Das eine existiert, das andere nicht. Ein Blick ins PHP-Handbuch hilft.

                          Tschö, Auge

                          --
                          Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
                          Wolfgang Schneidewind *prust*
                        2. Lieber Auge, deine Brille muss geputzt werden: mysqli_fetch_array gibt es ;-)

                          Die mysqli Funktionen haben zwei Implementierungen. Eine auf Objektbasis - die behalten dann ihren notwendigen Kontext (wie Connection oder Query) im Hinterkopf(-objekt). Und eine auf Funktionsbasis, da gibt's dann keinen Hinterkopf und Du musst ihnen den Kontext jeweils per Parameter mitgegeben.

                          Von dem her, was passiert, ist

                          $rows = $res->fetch_array()
                          $rows = mysqli_fetch_array($res)
                          

                          also synomym. Wer von den beiden der Fake ist und wer der direkte Zugang zur SQL-Engine, weiß ich nicht. Es ist auch egal. Hier steht, dass die Performance der beiden Varianten sich nicht signifikant unterscheidet und dass das Funktionsinterface eher für die Leute gemacht ist, die an das alte mysql gewöhnt sind.

                          Rolf

                          1. Hallo

                            Irrtum - mysqli_fetch_array gibt es

                            Dammich nochmal, warum wird die Funktion über die eigene Suche der PHP-Seite nicht gefunden? Und ich schreib' mir hier sinnlos die Finger fusslich …

                            Aus irgendwelchen Gründen - vielleicht weil es immer noch OO-Verweigerer gibt oder weil das Interface älter ist als brauchbarer OO Support in PHP - haben die mysqli Funktionen zwei Implementierungen.

                            Ich vermute mal, dass es beides ist. Die Implementierung ist nicht ganz neu und ja, es gibt Leute, die nicht OO programmieren. Warum auch nicht?

                            Tschö, Auge

                            --
                            Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
                            Wolfgang Schneidewind *prust*
                            1. Grins, du hast eine alte Fassung des Postings zitiert. Bin ich wieder mal aufgefallen. Die neue Fassung verlinkt auf die Doku-Seite, die die Interfaces vergleicht.

                              Die PHP Dokumenteure schreiben selbst, dass die Doku sich am OO Interface orientiert. Deshalb wird das prozedurale Interface nicht im Index sein. Gut wär's sicherlich schon...

                              Robo

                              1. Hallo

                                Grins, du hast eine alte Fassung des Postings zitiert. Bin ich wieder mal aufgefallen. Die neue Fassung verlinkt auf die Doku-Seite, die die Interfaces vergleicht.

                                Hmm? Soweit ich den Versionen entnehme, war der Link von Anfang an da und die URL des Links hat sich, über die Änderungen des Postings hinweg, nicht verändert.

                                Die PHP Dokumenteure schreiben selbst, dass die Doku sich am OO Interface orientiert. Deshalb wird das prozedurale Interface nicht im Index sein. Gut wär's sicherlich schon...

                                Die Doku darf sich soviel am OO-Stil orientieren, wie es deren Macher wollen. Dass mit dem Suchbegriff „mysqli_fetch_array“ nichts statt der für viele Funktionen existierenden Hinweisseite, dass dies ein Alias einer OO-Funktion sei, oder der von dir verlinkten Seite gefunden wird, ist mMn ärgerlich.

                                Tschö, Auge

                                --
                                Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
                                Wolfgang Schneidewind *prust*
        3. Kleiner Änderungsvorschlag:

          function tuWas() {
            global $db_connect, $andere_variable, ...;
            ...
          }
          

          Das ist reichlich undurchsichtig. Ich würde, wenn denn schon globale Variablen benutzt werden, das ersichtliche $GLOBALS nehmen.

          function test1() {
             $GLOBALS['ha'] = 'Test bestanden.';
             return true;
          }
          function test2() {
             if ( isset($GLOBALS['ha']) ) {
                 echo $GLOBALS['ha'], "\n";
             } else {
                 echo "Du hast Dich vertippt...\n";
             }
          }
          test1() && test2();