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

Problemi con l'associazione di un array imploso in un'istruzione preparata da MySQL

Lascia che ti risparmi un po' di problemi e ti dica che quello che stai cercando di fare non funzionerà comunque. Stai vincolando solo un parametro al tuo IN() chiamata di funzione. Tu pensi stai passando un elenco separato da virgole ma in realtà stai solo passando una stringa separata da virgole che viene trattata come un valore . Ciò significa che cercherai un record con un valore di "'[email protected] ', '[email protected] '" invece dei record che corrispondono a "[email protected] " o "[email protected] ".

Per superare questo è necessario:

  1. Genera dinamicamente la stringa dei tipi
  2. Usa call_user_func_array() per vincolare i tuoi parametri

Puoi generare la stringa di tipi in questo modo:

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

Tutto ciò che fa è creare una stringa di s 'è tanti caratteri quanti sono gli elementi nell'array.

Dovresti quindi associare i tuoi parametri usando call_user_func_array() in questo modo (notare che ho rimesso la parentesi per IN() funzione):

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

Ma se provi questo otterrai un errore su mysqli_stmt::bind_param() aspettandosi che il parametro due venga passato per riferimento:

Questo è un po 'fastidioso ma abbastanza facile da aggirare. Per aggirare il problema puoi utilizzare la seguente funzione:

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

Crea semplicemente una matrice di valori che sono riferimenti ai valori nel $selected Vettore. Questo è sufficiente per creare mysqli_stmt::bind_param() felice:

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

Modifica

A partire da PHP 5.6 ora puoi usare il ... operatore per renderlo ancora più semplice:

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