dedlfix: bind_param mit array möglich ?

Beitrag lesen

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";