Прав си, че първият случай е несигурен. Важно е да се разбере обаче, че изготвянето на израз има стойност само ако използвате променливи данни и/или изпълнявате една и съща заявка многократно. Ако изпълнявате обикновени оператори без променливи , можете просто да направите това:
$sql = "SELECT * from myTable WHERE this_column IS NOT NULL";
$result = $conn->query($sql);
И в крайна сметка ще получите PDOStatement
обект, с който да работите, точно както когато използвате PDO::exec()
.
За втория си случай, отново, до голяма степен си прав. Това, което се случва, е променливата, предадена на базата данни, е екранирана и цитирана (освен ако не посочите друго с третия аргумент на PDOStatement::bindParam()
, изпраща се като низ, което е добре в повечето случаи.) Така че заявката няма да се „провали“, ако се изпращат лоши данни. Той се държи точно така, сякаш сте предали валиден номер, който не съществува като идентификатор в базата данни. Има, разбира се, някои крайни случаи
където все още сте уязвими дори с правилно подготвено изявление.
Освен това, за да направите живота по-лесен, можете да използвате подготвени изявления като това, за да направите имплицитно обвързване:
$sql = "SELECT * FROM myTable WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->execute([":id"=>$id]);
Или дори така, с неименувани параметри:
$sql = "SELECT * FROM myTable WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->execute([$id]);
Естествено, повечето от това беше обяснено в коментарите, докато пишех отговора!