Akela: bind_param mit array möglich ?

Hallo,

ich versuche mich gerade an einer Datenbank. Hierfür möchte ich mit bind_param meine Variablen mappen, die ich vorher in einem prepare mit ? eingeführt habe.

Meine Frage ist: Kann man satt der Variablenaufzählung auch einfach ein array übergeben
Bsp (aus Handbuch):
$stmt = $mysqli->prepare( ... );
$stmt->bind_param('sssd', $code, $language, $official, $percent );

Bsp (gewünscht):
$mein_werte_array( 'rot', 'gelb', 'gruen' );
$stmt = $mysqli->prepare( ... );
$stmt->bind_param('sssd', $mein_werte_array );

Die Lösung unter gewünscht geht natürlich nicht (schon probiert) aber evtl. hat jemand einen Hinweis, wie man das ähnlich umsetzen kann.

ciao Akela

  1. echo $begrüßung;

    [mysqli_stmt::bind_param()]
    Kann man satt der Variablenaufzählung auch einfach ein array übergeben
    $stmt->bind_param('sssd', $code, $language, $official, $percent );

    Ja, das ist möglich, wenngleich auch etwas umständlich. Gegeben sei das Array $params mit den einzufügenden Werten. Mit der Funktion call_user_func_array() kann man Funktionen (und auch Methoden - siehe Pseudotyp callback) aufrufen und dabei ein Array mit den Parametern übergeben. Doch bind_param() ist etwas zickig und will unbedingt Variablen und nicht einfach nur Werte haben. In einem Array liegen aber keine Variablen, sondern nur Werte. Mit Trick 17 und einer foreach-Schleife kann man Referenzen erzeugen, die nun anstandslos von bind_param() genommen werden. Hinzu kommt noch als erster Parameter der $types-String. Ich erzeuge ihn aus der Anzahl der übergebenen Parameter. MySQL ist ja nicht wählerisch, wenn es Zahlen als String übergeben bekommt.

    foreach ($params as &$param); // hier gibt es nichts auszuführen  
    array_unshift($params, str_repeat('s', count($params)));  
    if (!call_user_func_array(array($stmt, 'bind_param'), $params))  
      ; // Fehlerbehandlung
    

    Noch etwas umständlicher ist das Abholen des Ergebnisses, denn das will ja über bind_result() auch wieder Variablen anbinden. Zunächst werden die Metadaten vom Ergebnis des Statements benötigt. Diese stehen nach der Ausführung von prepare() zur Verfügung. Dann wird für jede Ergebnisspalte ein Element in einem Array angelegt und der Referenz-Trick angewendet. Der Aufruf von bind_result erfolgt wieder mit call_user_func_array().

    if (!$meta = $stmt->result_metadata())  
      ; // Fehlerbehandlung  
    $values = array();  
    while ($field = $meta->fetch_field())  
      $values[$field->name] = null;  
    foreach ($values as &$reference); //nix auszuführen  
    if (!call_user_func_array(array($stmt, 'bind_result'), $values))  
      ; // Fehlerbehandlung
    

    Bei jedem fetch() ist es außerdem noch günstig, die Referenzen wieder aufzulösen, sonst zeigt immer alles auf das gleiche. Das ist notwendig wenn man sich ein fetchAll() erstellen will, das die gesamte Ergebnismenge in einem Array zurückliefert. Wenn man die Werte gleich ausgibt ist das "Dereferenzieren" nicht nötig.

    $result = array();  
    while ($stmt->fetch()) {  
      $row = array();  
      foreach ($values as $key => $value) // das selbe $values von oben  
        $row[$key] = $value;  
      $result[] = $row;  
    }
    

    echo "$verabschiedung $name";

    1. Hi,

      Danke für diese sehr ausführliche Antwort :-)