Vous avez raison de dire que le premier cas n'est pas sûr. Il est important de comprendre cependant que la préparation d'une instruction n'a de valeur que si vous utilisez des données variables et/ou exécutez la même requête à plusieurs reprises. Si vous exécutez des instructions simples sans variables , vous pouvez simplement faire ceci :
$sql = "SELECT * from myTable WHERE this_column IS NOT NULL";
$result = $conn->query($sql);
Et se retrouver avec un PDOStatement
objet avec lequel travailler, comme lorsque vous utilisez PDO::exec()
.
Pour votre deuxième cas, encore une fois, vous avez largement raison. Ce qui se passe, c'est que la variable transmise à la base de données est échappée et entre guillemets (sauf si vous spécifiez le contraire avec le troisième argument de PDOStatement::bindParam()
, il est envoyé sous forme de chaîne, ce qui convient dans la plupart des cas.) Ainsi, la requête "n'échouera" pas si de mauvaises données sont envoyées. Il se comporte exactement comme si vous aviez passé un numéro valide qui n'existait pas en tant qu'ID dans la base de données. Il y a, bien sûr, certains cas extrêmes
où vous êtes toujours vulnérable même avec une déclaration correctement préparée.
De plus, pour vous faciliter la vie, vous pouvez utiliser des instructions préparées comme celle-ci, pour faire une liaison implicite :
$sql = "SELECT * FROM myTable WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->execute([":id"=>$id]);
Ou même comme ça, avec des paramètres sans nom :
$sql = "SELECT * FROM myTable WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->execute([$id]);
Naturellement, la plupart de cela a été expliqué dans les commentaires pendant que je tapais la réponse !