Masz rację, że pierwszy przypadek jest niepewny. Ważne jest jednak, aby zrozumieć, że przygotowanie instrukcji ma wartość tylko wtedy, gdy używasz zmiennych danych i/lub wielokrotnie wykonujesz to samo zapytanie. Jeśli wykonujesz proste instrukcje bez zmiennych , możesz po prostu zrobić to:
$sql = "SELECT * from myTable WHERE this_column IS NOT NULL";
$result = $conn->query($sql);
I skończyć z PDOStatement
obiekt do pracy, tak jak w przypadku użycia PDO::exec()
.
W drugim przypadku, znowu, w dużej mierze masz rację. To, co się dzieje, to zmiana znaczenia zmiennej przekazywanej do bazy danych i cytowanie (chyba że określisz inaczej za pomocą trzeciego argumentu PDOStatement::bindParam()
, jest wysyłany jako ciąg znaków, co w większości przypadków wystarcza.) Zatem zapytanie nie "nie powiedzie się", jeśli zostaną wysłane złe dane. Zachowuje się dokładnie tak, jakbyś przekazał prawidłowy numer, który nie istnieje jako identyfikator w bazie danych. Są oczywiście niektóre skrajne przypadki
gdzie nadal jesteś podatny na ataki nawet z poprawnie przygotowanym oświadczeniem.
Ponadto, aby ułatwić sobie życie, możesz użyć przygotowanych oświadczeń, takich jak to, aby wykonać niejawne wiązanie:
$sql = "SELECT * FROM myTable WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->execute([":id"=>$id]);
Lub nawet tak, z nienazwanymi parametrami:
$sql = "SELECT * FROM myTable WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->execute([$id]);
Oczywiście większość z nich została wyjaśniona w komentarzach, kiedy pisałem odpowiedź!