Hai ragione sul fatto che il primo caso non è sicuro. È importante capire, tuttavia, che la preparazione di un'istruzione ha valore solo se si utilizzano dati variabili e/o si esegue ripetutamente la stessa query. Se stai eseguendo semplici istruzioni senza variabili , potresti semplicemente fare questo:
$sql = "SELECT * from myTable WHERE this_column IS NOT NULL";
$result = $conn->query($sql);
E finisci con un PDOStatement
oggetto con cui lavorare, proprio come quando usi PDO::exec()
.
Per il tuo secondo caso, ancora una volta, hai ampiamente ragione. Quello che sta succedendo è che la variabile passata al database viene sottoposta a escape e quotata (a meno che non specifichi diversamente con il terzo argomento a PDOStatement::bindParam()
, viene inviata come stringa che va bene per la maggior parte dei casi.) Quindi, la query non "fallirà" se vengono inviati dati errati. Si comporta esattamente come se avessi passato un numero valido che non esisteva come ID nel database. Ci sono, ovviamente, alcuni casi limite
dove sei ancora vulnerabile anche con una dichiarazione preparata correttamente.
Inoltre, per semplificarti la vita, puoi utilizzare istruzioni preparate come questa, per eseguire il binding implicito:
$sql = "SELECT * FROM myTable WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->execute([":id"=>$id]);
O anche così, con parametri senza nome:
$sql = "SELECT * FROM myTable WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->execute([$id]);
Naturalmente, la maggior parte di questo è stata spiegata nei commenti mentre stavo scrivendo la risposta!