Wie binden Sie mysqli bind_param Argumente dynamisch in PHP?

Ich habe gelernt, vorbereitete und gebundene statementen für meine SQL-Abfragen zu verwenden, und ich bin damit soweit gekommen, es funktioniert in Ordnung, aber es ist überhaupt nicht dynamisch, wenn es zu mehreren Parametern kommt oder wenn kein Parameter benötigt wird,

public function get_result($sql,$parameter) { # create a prepared statement $stmt = $this->mysqli->prepare($sql); # bind parameters for markers # but this is not dynamic enough... $stmt->bind_param("s", $parameter); # execute query $stmt->execute(); # these lines of code below return one dimentional array, similar to mysqli::fetch_assoc() $meta = $stmt->result_metadata(); while ($field = $meta->fetch_field()) { $var = $field->name; $$var = null; $parameters[$field->name] = &$$var; } call_user_func_array(array($stmt, 'bind_result'), $parameters); while($stmt->fetch()) { return $parameters; //print_r($parameters); } # close statement $stmt->close(); } 

So rufe ich die Objektklassen auf,

 $mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME); $output = new search($mysqli); 

Manchmal muss ich keine Parameter übergeben,

 $sql = " SELECT * FROM root_contacts_cfm "; print_r($output->get_result($sql)); 

Manchmal brauche ich nur einen Parameter,

 $sql = " SELECT * FROM root_contacts_cfm WHERE root_contacts_cfm.cnt_id = ? ORDER BY cnt_id DESC "; print_r($output->get_result($sql,'1')); 

Manchmal brauche ich nur mehr als einen Parameter,

 $sql = " SELECT * FROM root_contacts_cfm WHERE root_contacts_cfm.cnt_id = ? AND root_contacts_cfm.cnt_firstname = ? ORDER BY cnt_id DESC "; print_r($output->get_result($sql,'1','Tk')); 

Ich glaube also, dass diese Zeile für die obigen dynamischen Aufgaben nicht dynamisch genug ist,

 $stmt->bind_param("s", $parameter); 

Um ein bind_param dynamisch zu erstellen, habe ich dies in anderen Posts online gefunden.

 call_user_func_array(array(&$stmt, 'bind_params'), $array_of_params); 

Und ich habe versucht, etwas Code von php.net zu ändern, aber ich komme nirgendwohin,

 if (strnatcmp(phpversion(),'5.3') >= 0) //Reference is required for PHP 5.3+ { $refs = array(); foreach($arr as $key => $value) $array_of_param[$key] = &$arr[$key]; call_user_func_array(array(&$stmt, 'bind_params'), $array_of_params); } 

Warum? Irgendwelche Ideen, wie ich es zum Laufen bringen kann?

Oder vielleicht gibt es bessere Lösungen?

die Antwort für mysqli gefunden:

 public function get_result($sql,$types = null,$params = null) { # create a prepared statement $stmt = $this->mysqli->prepare($sql); # bind parameters for markers # but this is not dynamic enough... //$stmt->bind_param("s", $parameter); if($types&&$params) { $bind_names[] = $types; for ($i=0; $iexecute(); # these lines of code below return one dimentional array, similar to mysqli::fetch_assoc() $meta = $stmt->result_metadata(); while ($field = $meta->fetch_field()) { $var = $field->name; $$var = null; $parameters[$field->name] = &$$var; } call_user_func_array(array($stmt, 'bind_result'), $parameters); while($stmt->fetch()) { return $parameters; //print_r($parameters); } # the commented lines below will return values but not arrays # bind result variables //$stmt->bind_result($id); # fetch value //$stmt->fetch(); # return the value //return $id; # close statement $stmt->close(); } 

dann:

 $mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME); $output = new search($mysqli); $sql = " SELECT * FROM root_contacts_cfm ORDER BY cnt_id DESC "; print_r($output->get_result($sql)); $sql = " SELECT * FROM root_contacts_cfm WHERE root_contacts_cfm.cnt_id = ? ORDER BY cnt_id DESC "; print_r($output->get_result($sql,'s',array('1'))); $sql = " SELECT * FROM root_contacts_cfm WHERE root_contacts_cfm.cnt_id = ? AND root_contacts_cfm.cnt_firstname = ? ORDER BY cnt_id DESC "; print_r($output->get_result($sql, 'ss',array('1','Tk'))); 

Mysqli ist so lahm, wenn es darum geht. Ich denke, ich sollte nach PDO migrieren!

Mit PHP 5.6 können Sie dies einfach mit Hilfe des entpackenden Operators ( ...$var ) tun und get_result () anstelle von bind_result () verwenden.

 public function get_result($sql,$types = null,$params = null) { $stmt = $this->mysqli->prepare($sql); $stmt->bind_param($types, ...$params); if(!$stmt->execute()) return false; return $stmt->get_result(); } 

Beispiel:

 $mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME); $output = new search($mysqli); $sql = "SELECT * FROM root_contacts_cfm WHERE root_contacts_cfm.cnt_id = ? AND root_contacts_cfm.cnt_firstname = ? ORDER BY cnt_id DESC"; $res = $output->get_result($sql, 'ss',array('1','Tk')); while($row = res->fetch_assoc()){ echo $row['fieldName'] .'
'; }

Oder vielleicht gibt es bessere Lösungen ??

Diese Antwort hilft Ihnen nicht wirklich, aber Sie sollten ernsthaft erwägen, von mysqli zu PDO zu wechseln.

Der Hauptgrund dafür ist, dass PDO das tut, was Sie in mysqli mit eingebauten functionen tun wollen. Zusätzlich zur manuellen Param-Bindung kann die execute- Methode stattdessen ein Array von Argumenten verwenden.

PDO ist einfach zu erweitern, und das Hinzufügen von Convenience-Methoden, um alles-und-zurück zu holen, statt den Prepare-Execute-Tanz zu machen, ist sehr einfach.

Ich habe eine nette mysqli-class gefunden, kann dynamische Parameter handhaben und ist einfach zu benutzen

https://github.com/ajillion/PHP-MySQLi-Database-Class

Sie können den Quellcode darauf verweisen, wie er die Abfrage dynamisch erstellt

https://github.com/ajillion/PHP-MySQLi-Database-Class/blob/master/MysqliDb.php

Mit PHP 5.6 oder höher :

 $stmt->bind_param(str_repeat("s", count($data)), ...$data); 

Mit PHP 5.5 oder niedriger könnten Sie (und ich ) Folgendes erwarten:

 call_user_func_array( array($stmt, "bind_param"), array_merge(array(str_repeat("s", count($data))), $data)); 

… aber mysqli_stmt::bind_param erwartet, dass seine Parameter Referenzen sind, während dies eine Liste von Werten übergibt.

Sie können dies umgehen (obwohl es eine hässliche Problemumgehung ist), indem Sie zunächst ein Array von Referenzen auf das ursprüngliche Array erstellen.

 $references_to_data = array(); foreach ($data as &$reference) { $references_to_data[] = &$reference; } unset($reference); call_user_func_array( array($stmt, "bind_param"), array_merge(array(str_repeat("s", count($data))), $references_to_data));