sql >> Database teknologi >  >> RDS >> Mysql

Problemer med at binde et imploderet array til en mysql-forberedt erklæring

Lad mig spare dig for nogle problemer og fortælle dig, hvad du prøver at gøre, vil alligevel ikke virke. Du binder kun én parameter til din IN() funktionskald. Du tænker du sender en kommasepareret liste, men du sender faktisk kun en kommasepareret streng, der behandles som én værdi . Det betyder, at du vil søge efter én post med værdien "'[email protected] ', '[email protected] '" i stedet for poster, der matcher "[email protected] " eller "[email protected] ".

For at overvinde dette skal du:

  1. Generér din typestreng dynamisk
  2. Brug call_user_func_array() for at binde dine parametre

Du kan generere typestrengen som denne:

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

Alt dette gør er at oprette en streng af s 's det er lige så mange tegn som antallet af elementer i arrayet.

Du vil derefter binde dine parametre ved hjælp af call_user_func_array() som dette (bemærk, at jeg satte parentesen tilbage til 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 hvis du prøver dette vil du få en fejlmeddelelse om mysqli_stmt::bind_param() forventer, at parameter to sendes ved reference:

Dette er lidt irriterende, men let nok at omgås. For at omgå det kan du bruge følgende funktion:

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

Det opretter bare en række værdier, der er referencer til værdierne i $selected array. Dette er nok til at lave 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)));

Rediger

Fra og med PHP 5.6 kan du nu bruge ... operatør for at gøre dette endnu enklere:

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



  1. SQL Server-forespørgsel for at finde alle aktuelle databasenavne

  2. Kaldning af en databasevisning i Yii ved hjælp af Active Record

  3. betinget af dobbeltnøgleopdatering

  4. PHP PDO med foreach and fetch