2008-08-15 11 views
7

In einem Projekt, das ich gerade beende, habe ich eine objektrelationale Mapping-Lösung für PHP geschrieben und implementiert. Bevor die Zweifler und Träumer "Wie um alles in der Welt?" Ausrufen, entspann dich - ich habe keinen Weg gefunden, die späte statische Bindung zu machen - ich arbeite nur so herum, wie es nur geht.PHP + MYSQLI: Variable Parameter-/Ergebnisbindung mit vorbereiteten Anweisungen

Wie auch immer, ich verwende derzeit keine vorbereiteten Anweisungen zur Abfrage, weil ich keine Möglichkeit gefunden habe, eine variable Anzahl von Argumenten an die Methoden bind_params() oder bind_result() zu übergeben.

Warum muss ich eine variable Anzahl von Argumenten unterstützen, fragen Sie? Weil die Oberklasse meiner Modelle (denke an meine Lösung als gehackter PHP ActiveRecord-Möchtegern) dort ist, wo die Abfrage definiert ist, und so weiß die find() - Methode zum Beispiel nicht, wie viele Parameter sie binden müsste .

Jetzt habe ich bereits daran gedacht, eine Argumentliste zu erstellen und eine Zeichenfolge an eval() zu übergeben, aber diese Lösung gefällt mir nicht besonders - ich würde lieber meine eigenen Sicherheitskontrollen implementieren und weitergeben Aussagen.

Hat jemand irgendwelche Vorschläge (oder Erfolgsgeschichten) darüber, wie man das schafft? Wenn Sie mir helfen können, dieses erste Problem zu lösen, können wir vielleicht das Binden der Ergebnismenge angehen (etwas, von dem ich vermute, dass es schwieriger oder zumindest ressourcenintensiver ist, wenn es eine anfängliche Abfrage zur Bestimmung der Tabellenstruktur beinhaltet).

Antwort

13

In PHP können Sie eine variable Anzahl von Argumenten an eine Funktion oder Methode übergeben, indem Sie call_user_func_array verwenden. Ein Beispiel für ein Verfahren wäre:

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

Die Funktion wird als sein eigenes Argument übergibt mit jedem Elemente in dem Array genannt werden.

+0

Ich denke, dass sollte die Funktion 'statt 'bindparams' bind_param' werden. Zumindest benutze ich es mit meiner 'mysqli'-Version' $ stmt-> bind_param() ', nicht' $ stmt-> bindparams() '. Prost! –

1

Ich bin nicht bearbeiten dürfen, aber ich glaube, Anw im Code

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

Die Referenz vor $ nicht notwendig ist. Da $stmt das Objekt ist und bindparams die Methode in diesem Objekt ist, ist die Referenz nicht notwendig. Es sollte sein:

call_user_func_array(array($stmt, 'bindparams'), $array_of_params); 

Weitere Informationen finden Sie in der PHP-Handbuch auf Callback Functions

0
call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params); 

Haben Sie nicht für mich arbeiten in meiner Umgebung, aber diese Antwort setzte mich auf dem richtigen Weg Was.. tatsächlich gearbeitet wurde:

$sitesql = ''; 
$array_of_params = array(); 
foreach($_POST['multiselect'] as $value){ 
    if($sitesql!=''){ 
     $sitesql .= "OR siteID=? "; 
     $array_of_params[0] .= 'i'; 
     $array_of_params[] = $value; 
    }else{ 
     $sitesql = " siteID=? "; 
     $array_of_params[0] .= 'i'; 
     $array_of_params[] = $value; 
    } 
} 

$stmt = $linki->prepare("SELECT IFNULL(SUM(hours),0) FROM table WHERE ".$sitesql." AND week!='0000-00-00'"); 
call_user_func_array(array(&$stmt, 'bind_param'), $array_of_params); 
$stmt->execute(); 
2

Sie haben, um sicherzustellen, dass $ array_of_params ist Array von Links zu Variablen, nicht Werte der selbst Sollte sein:

$array_of_params[0] = &$param_string; //link to variable that stores types 

Und dann ...

$param_string .= "i"; 
$user_id_var = $_GET['user_id'];// 
$array_of_params[] = &$user_id_var; //link to variable that stores value 

Ansonsten (wenn es Array von Werten ist) Sie erhalten:

PHP Warning: Parameter 2 bis mysqli_stmt :: bind_param() erwartet eine Referenz


zu sein

Ein weiteres Beispiel:

$bind_names[] = implode($types); //putting types of parameters in a string 
for ($i = 0; $i < count($params); $i++) 
{ 
    $bind_name = 'bind'.$i; //generate a name for variable bind1, bind2, bind3... 
    $$bind_name = $params[$i]; //create a variable with this name and put value in it 
    $bind_names[] = & $$bind_name; //put a link to this variable in array 
} 

und BOOOOOM:

call_user_func_array(array ($stmt, 'bind_param'), $bind_names);