Prepared Statements und bind_result mit wechselnder Anzahl von Parametern

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Prepared Statements und bind_result mit wechselnder Anzahl von Parametern

    Ich möchte mir ein Modul schreiben, dass ich in bei allen meinen Seiten verwenden kann. Dieses Modul soll alle Datenbankzugriffe organisieren (PHP/MySQL).

    So weit, so einfach. Leider spricht der Vorteil von Prepared Statements, dass sie nicht manipulierbar sein sollen, gegen dieses Vorhaben.

    Bisher binde ich die results so:

    $GLOBALS['db_obj']->bind_result($GLOBALS['foo'], $GLOBALS['bar'], $GLOBALS['baz']);

    Aber da natürlich die Anzahl meiner Parameter variiert, muss ich das jetzt irgendwie umgehen. Also hab ich Google bemüht und dabei call_user_func_array gefunden.

    Zu meiner Schande muss ich gestehen, dass ich überhaupt nicht verstehe, was da genau passiert. Das geht so weit, dass ich nicht mal weiß, wo ich anfangen soll.

    Ich hab ja schon mit function() gearbeitet. Aber mir ist überhaupt nicht klar, was ich mit einer Funktion machen soll, was nicht auch mit einer While-Schleife funktionieren müsste. Was es aber natürlich nicht tut.

    So wie ich das sehe ist der Hauptunterschied zwischen function() und call_user_func_array() der, dass das eine mehrere Variablen und das andere ein Array mit den zu verarbeitenden Daten erhält. Aber wieso kann das jetzt mein Problem lösen?

    Danke für jede Art Verständnishilfe.

  • #2
    So ungefähr ab hier ist der Post für mich nicht mehr nachvollziehbar:

    Bisher binde ich die results so:

    $GLOBALS['db_obj']->bind_result($GLOBALS['foo'], $GLOBALS['bar'], $GLOBALS['baz']);

    Aber da natürlich die Anzahl meiner Parameter variiert, muss ich das jetzt irgendwie umgehen.
    Dein $GLOBALS['db_obj'] ist ein MySQLi_STMT, nehme ich an?

    Wie sollen da denn die Parameter variieren? Und wenn sie variieren, wieso übergibst du dann nicht einfach mehr Argumente an die Methode?

    Kommentar


    • #3
      Hallo und willkommen im Forum,

      zunächst mal finde ich es bedenklich, mit $GLOBALS zu arbeiten. Damit schaffst du dir eine unübersichtliche Landschaft von wilden Variablen. Darin liegt z. B. schon einer der Vorteile von Funktionen, dass ihre Variablen nur dort gelten und Namenskollisionen ausgeschlossen sind.

      Dein $db_obj ist eigentlich keins, sondern offensichtlich ein MySQLi_Stmt. Da ein solches nur eine ganz bestimmte Abfrage repräsentiert, kann es eigentlich gar nicht sein, dass du dort unterschiedliche Parameteranzahlen hast.

      Wenn du allerdings meinst, dass du ein Codestück für völlig unterschiedliche Statements verwendest, dann verstehe ich es, aber mir leuchtet dabei nicht ein, wei du das ohne Funktionen bewerkstelligen willst (die ja jeweils einen eigenen Gültigkeitsbereich für jeden Aufruf haben).

      Zum Thema call_user_func_array: Damit kann man Parameterlisten für Funktionen dynamisch zusammenbauen, statt die Parameter fest in den Aufruf einzubauen.

      PHP-Code:
      myFunc($a$b$c); // Es werden 3 Parameter übergeben
      myFunc($d$e); // Es werden 2 Parameter übergeben

      $params = array(); // dynamische Parameter; können unterschiedlich viele sein
      $params[] = 1;
      $params[] = "Hallo Welt!";
      $params[] = false;
      myFunc($params); // FALSCH, denn jetzt wird nur ein Parameter (ein Array) übergeben

      // Lösung:
      call_user_func_array("myFunc"$params); // jedes Element wird sozusagen als einzelner Parameter übergeben

      // Das kann man sich ungefähr so vorstellen:
      switch (count($params)) {
          case 
      0myFunc(); break;
          case 
      1myFunc($params[0]); break;
          case 
      2myFunc($params[0], $params[1]); break;
          case 
      3myFunc($params[0], $params[1], $params[2]); break;
          case 
      4myFunc($params[0], $params[1], $params[2], $params[3]); break;
          
      // u. s. w.

      Gruß,

      Amica
      [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
      Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
      Super, danke!
      [/COLOR]

      Kommentar


      • #4
        So hab ich das bisher gemacht:

        PHP-Code:
        if ($GLOBALS['db_obj']=$GLOBALS['db']->prepare($GLOBALS['db_sql_stm'])) {
            
        $GLOBALS['db_obj']->execute();
            
        $GLOBALS['db_obj']->bind_result($GLOBALS['foo'], $GLOBALS['bar'], $GLOBALS['baz']);
            
        $GLOBALS['cou_ds']=0;
            while (
        $GLOBALS['db_obj']->fetch()) {
                
        $GLOBALS['pag'][$GLOBALS['cou_ds']]['pag_id']=$GLOBALS['pag_id'];
                
        $GLOBALS['pag'][$GLOBALS['cou_ds']]['foo']=$GLOBALS['foo'];
                
        $GLOBALS['pag'][$GLOBALS['cou_ds']]['bar']=$GLOBALS['bar'];
                
        $GLOBALS['pag'][$GLOBALS['cou_ds']]['baz']=$GLOBALS['baz'];
                
        $GLOBALS['cou_ds']++;
            }
            
        $GLOBALS['db_obj']->close();
        } else {
            
        $GLOBALS['err_db']='Error '.$GLOBALS['db']->errno.' - '.$GLOBALS['db']->error;
            echo 
        '<br>'.$GLOBALS['err_db'].'<br>';

        Okay, das mit der Gültigkeit der Variablen nur innerhalb der Funktion hatte ich schon wieder vergessen.

        Genau, ich möchte ein Modul für alle Statements verwenden. Und ich will lieber eine Funktion verwenden als ein switch/case-Konstrukt.

        Aber, ich will es halt verstehen. Leider verwirrt mich auch Dein Beispiel, Amica. Sorry, aber bei diesem call_user_func_array hab ich das Gefühl, als sehe ich den Wald vor lauter Bäumen nicht.

        Wenn das Funktionen sein sollen, dann fehlt der Ausdruck "function", oder? Und auch irgendwas, was dem dem Objekt sagt, was damit geschehen zu hat. Oder liege ich völlig falsch?

        PHP-Code:
        myFunc($a$b$c); // Es werden 3 Parameter übergeben
        myFunc($d$e); // Es werden 2 Parameter übergeben 
        Das is klar, hier setzt Du ein Array.

        PHP-Code:
        $params = array(); // dynamische Parameter; können unterschiedlich viele sein
        $params[] = 1;
        $params[] = "Hallo Welt!";
        $params[] = false
        Das sagt mir wieder nix:

        PHP-Code:
        myFunc($params); // FALSCH, denn jetzt wird nur ein Parameter (ein Array) übergeben 
        Okay, damit könnte ich was anfangen, wenn ich nicht 2 unterschiedliche myFunc hätte und darin etwas mehr stünde.

        PHP-Code:
        // Lösung:
        call_user_func_array("myFunc"$params); // jedes Element wird sozusagen als einzelner Parameter übergeben 
        Das will ich nicht:

        PHP-Code:
        // Das kann man sich ungefähr so vorstellen:
        switch (count($params)) {
            case 
        1myFunc($params[0]); break;
            case 
        2myFunc($params[0], $params[1]); break;
            case 
        3myFunc($params[0], $params[1], $params[2]); break;
            case 
        4myFunc($params[0], $params[1], $params[2], $params[3]); break;
            
        // u. s. w.

        Sorry, wenn ich Euch Eure Zeit stehle, mit meinem Unverständnis.
        Zuletzt geändert von culturo; 21.06.2011, 19:01.

        Kommentar


        • #5
          Also ich sehe bei deinen $GLOBALS den Wald vor lauter Bäumen nicht, was aber z. T. daran liegt, dass ich mir die Augen zuhalten muss.

          Das function-Schlüsselwort wird bei der Definition einer Funktion benötigt, aber nicht bei ihrem Aufruf.

          PHP-Code:
          // Definition
          function multiply ($x$y) {
              return 
          $x $y;
          }

          // Aufrufe
          $prod multiply(34); // prod ist jetzt 12
          echo multiply($prod13); // 156 wird ausgegeben 
          [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
          Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
          Super, danke!
          [/COLOR]

          Kommentar


          • #6
            Hab mir das nochmal mit dem Register Golbals angesehen. Jetzt weiß ich auch nicht mehr, warum ich mir damals angewöhnt hab, die globalen Variablen als $GLOBALS auszuzeichnen.

            Nun gut, so sieht der Code jetzt aus:

            PHP-Code:
            if ($db_obj=$db->prepare($db_sql_stm)) {
                
            $db_obj->execute();
                
            $db_obj->bind_result($foo$bar$baz);
                
            $cou_ds=0;
                while (
            $db_obj->fetch()) {
                    
            $pag[$cou_ds]['foo']=$foo;
                    
            $pag[$cou_ds]['bar']=$bar;
                    
            $pag[$cou_ds]['baz']=$baz;
                    
            $cou_ds++;
                }
                
            $db_obj->close();
            } else {
                
            $err_db='Error '.$db->errno.' - '.$db->error;
                echo 
            '<br>'.$err_db.'<br>';

            So sieht übrigens $db_sql_stm beispielsweise aus.

            PHP-Code:
            SELECT foobarbaz FROM pag
            Jetzt hab ich das mal verbaut:

            PHP-Code:
            function bnd_res ($db_obj$db_cm// Das natürlich vor dem Aufruf
            {
                
            $db_obj->bind_result($db_cm);
            }
             
            call_user_func_array('bnd_res'$db_cm); // Das anstatt $db_obj->bind_result($foo, $bar, $baz); 
            Dann bekomme ich das:

            Fatal error: Call to a member function bind_result() on a non-object in x.inc on line x

            Aber das war natürlich klar. Ist es nicht so, dass wenn das funktioniert hätte, ich gar keine Funktion brauchen würde, sondern einfach das $db_obj->bind_result($db_cm); anstatt $db_obj->bind_result($foo, $bar, $baz); schreiben müsste?

            Ist natürlich ne rhetorische Frage. Habs ja ausprobiert.

            Was muss ich ändern, damit ich mit variabler Anzahl an Parametern arbeiten kann?
            Zuletzt geändert von culturo; 22.06.2011, 11:12. Grund: Hab das Wichtigste vergessen.

            Kommentar


            • #7
              Warum nimmst du nicht PDO? Da kannst du mit Prepared Statements arbeiten, ohne gleichzeitig das Ergebnis zeilenweise binden zu müssen.
              [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
              Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
              Super, danke!
              [/COLOR]

              Kommentar


              • #8
                Zitat von culturo Beitrag anzeigen
                Hab mir das nochmal mit dem Register Golbals angesehen. Jetzt weiß ich auch nicht mehr, warum ich mir damals angewöhnt hab, die globalen Variablen als $GLOBALS auszuzeichnen.
                Du sollst gar keine globalen Variablen verwenden! Global ist böse! Kein Mensch braucht global.

                Kommentar

                Lädt...
                X