Al igual que con casi todas las preguntas "¿Cómo hago SQL desde dentro de PHP?", realmente debe usar declaraciones preparadas. No es tan difícil:
$ids = array(2, 4, 6, 8);
// prepare an SQL statement with a single parameter placeholder
$sql = "UPDATE MyTable SET LastUpdated = GETDATE() WHERE id = ?";
$stmt = $mysqli->prepare($sql);
// bind a different value to the placeholder with each execution
for ($i = 0; $i < count($ids); $i++)
{
$stmt->bind_param("i", $ids[$i]);
$stmt->execute();
echo "Updated record ID: $id\n";
}
// done
$stmt->close();
Alternativamente, puedes hacerlo así:
$ids = array(2, 4, 6, 8);
// prepare an SQL statement with multiple parameter placeholders
$params = implode(",", array_fill(0, count($ids), "?"));
$sql = "UPDATE MyTable SET LastUpdated = GETDATE() WHERE id IN ($params)";
$stmt = $mysqli->prepare($sql);
// dynamic call of mysqli_stmt::bind_param hard-coded eqivalent
$types = str_repeat("i", count($ids)); // "iiii"
$args = array_merge(array($types), $ids); // ["iiii", 2, 4, 6, 8]
call_user_func_array(array($stmt, 'bind_param'), ref($args)); // $stmt->bind_param("iiii", 2, 4, 6, 8)
// execute the query for all input values in one step
$stmt->execute();
// done
$stmt->close();
echo "Updated record IDs: " . implode("," $ids) ."\n";
// ----------------------------------------------------------------------------------
// helper function to turn an array of values into an array of value references
// necessary because mysqli_stmt::bind_param needs value refereces for no good reason
function ref($arr) {
$refs = array();
foreach ($arr as $key => $val) $refs[$key] = &$arr[$key];
return $refs;
}
Agregue más marcadores de posición de parámetros para otros campos a medida que los necesite.
¿Cuál elegir?
-
La primera variante funciona con un número variable de registros de forma iterativa, accediendo a la base de datos varias veces. Esto es más útil para las operaciones de ACTUALIZACIÓN e INSERCIÓN.
-
La segunda variante también funciona con un número variable de registros, pero llega a la base de datos solo una vez. Esto es mucho más eficiente que el enfoque iterativo, obviamente solo puede hacer lo mismo con todos los registros afectados. Esto es más útil para las operaciones SELECCIONAR y ELIMINAR, o cuando desea ACTUALIZAR varios registros con los mismos datos.
¿Por qué declaraciones preparadas?
- Las declaraciones preparadas son mucho más seguras porque hacen que los ataques de inyección SQL sean imposibles. Esta es la razón principal para usar declaraciones preparadas, incluso si es más trabajo escribirlas. Un hábito sensato que se debe adoptar es:siempre use declaraciones preparadas, incluso si cree que "no es realmente necesario". El descuido vendrá y te morderá a ti (o a tus clientes).
- Reutilizar la misma declaración preparada varias veces con diferentes valores de parámetros es más eficiente que enviar múltiples cadenas SQL completas a la base de datos, porque la base de datos solo necesita compilar la declaración una vez y también puede reutilizarla.
- Solo los valores de los parámetros se envían a la base de datos en
execute()
, por lo que se necesitan menos datos para pasar por el cable cuando se usa repetidamente.
En bucles más largos, la diferencia de tiempo de ejecución entre usar una declaración preparada y enviar SQL sin formato será notable.