Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Probleme beim Binden eines implodierten Arrays an eine vorbereitete mysql-Anweisung

Lassen Sie mich Ihnen etwas Ärger ersparen und Ihnen sagen, was Sie versuchen zu tun, wird sowieso nicht funktionieren. Sie binden nur einen Parameter an Ihr IN() Funktionsaufruf. Sie denken Sie übergeben eine kommagetrennte Liste, aber Sie übergeben tatsächlich nur eine kommagetrennte Zeichenfolge, die als ein Wert behandelt wird . Das bedeutet, dass Sie nach einem Datensatz suchen mit dem Wert „'[email protected] ', '[email protected] '" anstelle von Datensätzen, die mit "[email protected] " übereinstimmen " oder "[email protected] ".

Um dies zu überwinden, müssen Sie:

  1. Generieren Sie dynamisch Ihren Typ-String
  2. Verwenden Sie call_user_func_array() um Ihre Parameter zu binden

Sie können die Typenzeichenfolge wie folgt generieren:

$types = str_repeat('s', count($selected));

Alles, was dies tut, ist eine Zeichenfolge von s zu erstellen Das sind so viele Zeichen wie die Anzahl der Elemente im Array.

Sie würden dann Ihre Parameter mit call_user_func_array() binden so (beachten Sie, dass ich die Klammer für IN() wieder eingefügt habe Funktion):

if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN (?)")) {
    call_user_func_array(array($stmt, "bind_param"), array_merge($types, $selected));

Aber wenn Sie dies versuchen, erhalten Sie eine Fehlermeldung über mysqli_stmt::bind_param() erwartet, dass Parameter zwei als Referenz übergeben wird:

Das ist etwas nervig, aber leicht genug zu umgehen. Um dies zu umgehen, können Sie die folgende Funktion verwenden:

function refValues($arr){ 
    $refs = array(); 
    foreach($arr as $key => $value) 
        $refs[$key] = &$arr[$key]; 
    return $refs; 
} 

Es erstellt lediglich ein Array von Werten, die Verweise auf die Werte in $selected sind Reihe. Dies reicht aus, um mysqli_stmt::bind_param() zu erstellen glücklich:

if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN (?)")) {
    call_user_func_array(array($stmt, "bind_param"), array_merge($types, refValues($selected)));

Bearbeiten

Ab PHP 5.6 können Sie nun den ... verwenden Operator, um dies noch einfacher zu machen:

$stmt->bind_param($types, ...$selected);