sql >> Databasteknik >  >> RDS >> Mysql

Problem med att binda en imploderad array till en mysql-förberedd sats

Låt mig rädda dig lite problem och berätta att det du försöker göra kommer inte att fungera ändå. Du binder bara en parameter till din IN() funktionsanrop. Du tänker du skickar en kommaseparerad lista men du skickar faktiskt bara en kommaseparerad sträng som behandlas som ett värde . Det betyder att du kommer att söka efter en post med värdet "'[email protected] ', '[email protected] '" istället för poster som matchar "[email protected] " eller "[email protected] ".

För att övervinna detta måste du:

  1. Generera din typsträng dynamiskt
  2. Använd call_user_func_array() för att binda dina parametrar

Du kan generera typsträngen så här:

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

Allt detta gör är att skapa en sträng av s 's det är lika många tecken som antalet element i arrayen.

Du skulle sedan binda dina parametrar med call_user_func_array() så här (märk på att jag sätter tillbaka parentesen för IN() 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));

Men om du försöker detta kommer du att få ett felmeddelande om mysqli_stmt::bind_param() förväntar sig att parameter två ska skickas med referens:

Det här är lite irriterande men lätt nog att komma runt. För att komma runt det kan du använda följande funktion:

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

Det skapar bara en uppsättning värden som är referenser till värdena i $selected array. Detta är tillräckligt för att göra mysqli_stmt::bind_param() glad:

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

Redigera

Från och med PHP 5.6 kan du nu använda ... operatör för att göra detta ännu enklare:

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



  1. Ändra en kolumntyp till längre strängar i skenor

  2. Jag måste dra data baserat på dess exakta sekvens i en array

  3. mysql-fråga för att få födelsedagar för de kommande 10 dagarna

  4. Varför tillåter MySQL grupp efter frågor UTAN aggregatfunktioner?