Tal como acontece com quase todas as perguntas "Como faço SQL de dentro do PHP" - Você realmente deve usar declarações preparadas. Não é tão 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, você pode fazer assim:
$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;
}
Adicione mais espaços reservados de parâmetro para outros campos conforme necessário.
Qual escolher?
-
A primeira variante trabalha com um número variável de registros de forma iterativa, atingindo o banco de dados várias vezes. Isso é mais útil para operações UPDATE e INSERT.
-
A segunda variante também funciona com um número variável de registros, mas atinge o banco de dados apenas uma vez. Isso é muito mais eficiente do que a abordagem iterativa, obviamente, você só pode fazer a mesma coisa com todos os registros afetados. Isso é mais útil para operações SELECT e DELETE ou quando você deseja ATUALIZAR vários registros com os mesmos dados.
Por que preparar declarações?
- As instruções preparadas são muito mais seguras porque impossibilitam os ataques de injeção de SQL. Esta é a principal razão para usar instruções preparadas, mesmo que seja mais trabalhoso escrevê-las. Um hábito sensato para adquirir é:sempre use declarações preparadas, mesmo que você ache que "não é realmente necessário". A negligência virá e morderá você (ou seus clientes).
- Reutilizar a mesma instrução preparada várias vezes com valores de parâmetro diferentes é mais eficiente do que enviar várias strings SQL completas para o banco de dados, porque o banco de dados só precisa compilar a instrução uma vez e também pode reutilizá-la. l>
- Somente os valores dos parâmetros são enviados ao banco de dados em
execute()
, portanto, menos dados precisam passar pela rede quando usados repetidamente.
Em loops mais longos, a diferença de tempo de execução entre o uso de uma instrução preparada e o envio de SQL simples se tornará perceptível.