sql >> Base de Datos >  >> RDS >> Mysql

Problemas para vincular una matriz implosionada en una declaración preparada de mysql

Déjame ahorrarte algunos problemas y decirte que lo que estás tratando de hacer no funcionará de todos modos. Solo está vinculando un parámetro a su IN() Llamada de función. Tu piensas está pasando una lista separada por comas, pero en realidad solo está pasando una cadena separada por comas que se trata como un valor . Esto significa que buscará un registro con un valor de "'[email protected] ', '[email protected] '" en lugar de registros que coincidan con "[email protected] " o "[email protected] ".

Para superar esto necesitas:

  1. Genera dinámicamente tu cadena de tipos
  2. Utilice call_user_func_array() para vincular sus parámetros

Puede generar la cadena de tipos como esta:

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

Todo lo que hace es crear una cadena de s 's que tiene tantos caracteres como el número de elementos en la matriz.

Luego vincularía sus parámetros usando call_user_func_array() así (observa que puse el paréntesis de nuevo para IN() función):

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

Pero si intenta esto obtendrá un error sobre mysqli_stmt::bind_param() esperando que el parámetro dos se pase por referencia:

Esto es un poco molesto pero bastante fácil de solucionar. Para evitarlo, puede utilizar la siguiente función:

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

Simplemente crea una matriz de valores que son referencias a los valores en el $selected formación. Esto es suficiente para hacer mysqli_stmt::bind_param() feliz:

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

Editar

A partir de PHP 5.6 ahora puede usar ... operador para hacer esto aún más simple:

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