Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] call_user_func_array und bind_param Problem

Einklappen

Neue Werbung 2019

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

  • #16
    Zitat von Paul.Schramenko Beitrag anzeigen
    Ziemlich dreist für jemanden, der Hilfe sucht...
    Wie man in den Wald ruft so schallt es heraus, ich muss mich ja nich von ihm wie nen Idiot hinstellen lassen nur weil ich Anfänger in der Materie bin oder?
    Des weiteren ist der Aufruf an der Stelle falsch.
    PHP-Code:
    function set_parameter($parameter, &$value) {
        
    $this->params[$parameter] = $value;

    Das & muss in den Funktionskopf, wo der Parameter übergeben wird!
    Ja das hab ich mal ausprobiert, wenn ich das & allerdings in den Funktionskopf schreibe bekomm ich folgende Fehlermeldung:
    Fatal error: Cannot pass parameter 2 by reference
    Liegt das vielleicht daran das beim Aufruf ja keine Variable sondern direkt ein String übergeben wird?
    Nachtrag:
    Außerdem finde ich diese Klasse auch recht unnötig... Ich würde dir eher empfehlen dir eine DB-Klasse zu schreiben, mit der du einfacher SQL-Queries ausführen kannst... Würde denke ich mehr Sinn machen. Und wenn du dafür keine Lust hast, such dir eine im Netz oder benutz PEAR
    Doch, ich denke wenn das dort oben läuft werd ich auch mal versuchen nen praktischen Nutzen aus der Klasse zu ziehen, aber im Moment gehts halt hauptsächlich ums Lernen. Es gibt nicht mal ein Projekt zu der Klasse, sie soll einfach nur funktionieren.

    @Woskamp: Prepared Statements funktionieren bei PDO und MySQLi von der Handhabung her doch gleich? Was in den Funktionen passiert weiß ich zwar nicht, aber ich denke dass das Problem eher bei dem verwendeten Array und dessen Aufruf liegt.

    Kommentar


    • #17
      Zitat von Ballamann Beitrag anzeigen
      Liegt das vielleicht daran das beim Aufruf ja keine Variable sondern direkt ein String übergeben wird?
      Ja.
      "My software never has bugs, it just develops random features."
      "Real programmers don't comment. If it was hard to write, it should be hard to understand!"

      Kommentar


      • #18
        und? gibts ne Möglichkeit das zu lösen?

        Kommentar


        • #19
          Eine Referenz ist ein Zeiger auf eine Variable im Speicher.
          Wohin willst du zeigen, wenn du keine Variable hast sondern diesen String einfach übergibst?
          "My software never has bugs, it just develops random features."
          "Real programmers don't comment. If it was hard to write, it should be hard to understand!"

          Kommentar


          • #20
            Das leuchtet ein. Nur wie löse ich dann das ganze Problem, dass die übergebenen Werte so in das Array übernommen werden das auch Funktionen wie bind_param() richtig funktionieren?

            Fällt dir spontan ne Möglichkeit ein set_parameter() umzuschreiben?

            Kommentar


            • #21
              Sorry, mir erschließt sich das aktuelle Probleme nicht so richtig und ich bin gerade nicht in der Stimmung, den gesamten Thread nachvollziehen zu wollen. Aber ich habe neulich in einem anderen Kontext mal das hier gebastelt:

              PHP-Code:
              <?php

              class Test
              {
                  protected 
              $_mysqli_stmt;
                  protected 
              $_mysqli;

                  public function 
              __construct($server$user$password$db)
                  {
                      
              $this->_mysqli = new mysqli($server$user$password);
                      
              $this->_mysqli->select_db($db);
                      
              $this->_mysqli_stmt $this->_mysqli->stmt_init();
                  }

                  
              /**
                   *
                   * @see http://www.php.net/manual/en/mysqli-stmt.bind-param.php#96770
                   */
                  
              protected function _refValues($arr){
                      if (
              strnatcmp(phpversion(),'5.3') >= 0//Reference is required for PHP 5.3+
                      
              {
                          
              $refs = array();
                          foreach(
              $arr as $key => $value)
                              
              $refs[$key] = &$arr[$key];
                          return 
              $refs;
                      }
                      return 
              $arr;
                  } 

                  public function 
              insert($table$data)
                  {
                      
              $sql 'INSERT INTO `' $this->_mysqli->escape_string($table) . '`';

                      
              // Feldnamen hinzufügen
                      
              $escapedKeys array_map(array($this->_mysqli'escape_string'), array_keys($data));
                      
              $sql .= ' (`' implode('`, `'$escapedKeys) . '`)';
                   
                      
              // Platzhalter für Werte hinzufügen
                      
              $sql .= ' VALUES (' implode(', 'array_fill(0count($data), '?')) . ')';

                      
              // Feldtypen ermitteln
                      
              $type '';
                      
              $values array_values($data);

                      foreach (
              $values as $value) {
                          if (
              is_int($value)) {
                              
              $type .= 'i';
                          } else if (
              is_double($value)) {
                              
              $type .= 'd';
                          } else {
                              
              $type .= 's';
                          }
                      }

                      if (!(
              $this->_mysqli_stmt->prepare($sql))) {
                          return 
              FALSE;
                      }

                      if (!
              call_user_func_array(array($this->_mysqli_stmt"bind_param"),
                          
              array_merge(array($type), $this->_refValues($data)))
                      ) {            
                          return 
              FALSE;
                      }

                      if (!(
              $this->_mysqli_stmt->execute())) {
                          return 
              FALSE;
                      }
                      
                      if ((
              $this->_mysqli_stmt->affected_rows) <= 0) {
                          return 
              FALSE;
                      }
                      
                      return 
              TRUE;
                  }
              }

              $t = new Test('localhost''user''pass''dbname');

              $data = array(
                  
              'headline'  => 'db-test',
                  
              'text'      => 'eins, zwei, drei, vier',
                  
              'author_id' => 12
              );

              $f $t->insert('news'$data);

              if (
              $f == false) {
                  echo 
              'Fehler';
              } else {
                  echo 
              'Erfolg';
              }
              Vielleicht hilft es ja. (Bitte keine Kommentare über den Sinngehalt des Codes. Ich weiß, dass der fast völlig zweckfrei ist. )

              Edit: Zusammengefasst: Es gibt da an einer Stelle ein abweichendes Verhalten ab PHP 5.3 (siehe verlinkter Post). Benutzt du PHP 5.3?

              Kommentar


              • #22
                Danke mermshaus!

                Durch deinen Beitrag hab ich wieder ein wenig google gequält und bin schließlich auf diese Seite hier gestoßen: klick

                Des Rätsels Lösung besteht darin von meinem Array $params[] eine Kopie mit Referenzen auf dieses Array zu erstellen. Danach kann ich wie gewünscht $params verändern und es funktioniert. Dickes Danke!

                Kommentar


                • #23
                  Ich weiß, das der Thread älter ist. Da aber scheinbar häufiger Leute vor diesem Problem stehen (Aufruf von bind_param mit unbekannter Anzahl Parameter), und ich kürzlich ebenfalls, hier noch eine Alternative zu dem Workaround für PHP 5.3+ (setzen der Referenzen für die Array-Elemente in einer eigenen Funktion).
                  Durch Nutzung von Reflection spart man sich die Zusatzfunktion und wird in der Performance etwas schneller, allerdings hat man für bind_param zwei Zeilen Code mehr:
                  PHP-Code:
                  $db     = new mysqli("localhost","root","","tests"); 
                  $res    $db->prepare("INSERT INTO test SET test2=?,test3=?"); 
                  $refArr = array("si","hallo",1); 
                  $ref    = new ReflectionClass('mysqli_stmt'); 
                  $method $ref->getMethod("bind_param"); 
                  $method->invokeArgs($res,$refArr); 
                  $res->execute(); 
                  Und noch ein Hinweis der zwar generell bind_param() betrifft, bei der hier angesprochenen Problemstellung aber immer auftritt: Vorsicht beim binden von Array-Elementen wenn das Statement mehrmals mit wechselnden Values durchgeführt werden soll!
                  Die Array-Values müssen EXPLIZIT ihrem jeweiligen Key zugewiesen werden. Eine Neugenerierung des kompletten Arrays zerstört die Referenzen, auch bei identischen Keys.

                  Beispiele:
                  PHP-Code:
                  $db     = new mysqli("localhost","root","","tests"); 
                  $res    $db->prepare("INSERT INTO test SET test2=?,test3=?"); 
                  $refArr = array("si","hallo",1); 
                  $ref    = new ReflectionClass('mysqli_stmt'); 
                  $method $ref->getMethod("bind_param"); 
                  $method->invokeArgs($res,$refArr); 
                  $res->execute(); 
                  $refArr = array("si","ciao",2);
                  $res->execute();
                  // Trägt zweimal die Values "hallo" und 1 ein


                  $db     = new mysqli("localhost","root","","tests"); 
                  $res    $db->prepare("INSERT INTO test SET test2=?,test3=?"); 
                  $refArr = array(0=>"si",1=>"hallo",2=>1); 
                  $ref    = new ReflectionClass('mysqli_stmt'); 
                  $method $ref->getMethod("bind_param"); 
                  $method->invokeArgs($res,$refArr); 
                  $res->execute(); 
                  $refArr = array(0=>"si",1=>"ciao",2=>2);
                  $res->execute();
                  //  Trägt zweimal die Values "hallo" und 1 ein


                  $db     = new mysqli("localhost","root","","tests"); 
                  $res    $db->prepare("INSERT INTO test SET test2=?,test3=?"); 
                  $refArr = array(0=>"si",1=>"hallo",2=>1); 
                  $ref    = new ReflectionClass('mysqli_stmt'); 
                  $method $ref->getMethod("bind_param"); 
                  $method->invokeArgs($res,$refArr); 
                  $res->execute(); 
                  $refArr[1] = "ciao";
                  $refArr[2] = 2;
                  $res->execute();
                  // Trägt wie gewünscht beim ersten execute() "hallo" und 1 ein, beim zweiten execute() "ciao" und 2 

                  Kommentar

                  Lädt...
                  X