Pernyataan yang Disiapkan PHP MySQL
Pernyataan yang disiapkan sangat berguna untuk melawan injeksi SQL.
Pernyataan yang Disiapkan dan Parameter Terikat
Pernyataan yang disiapkan adalah fitur yang digunakan untuk mengeksekusi pernyataan SQL yang sama (atau serupa) berulang kali dengan efisiensi tinggi.
Pernyataan yang disiapkan pada dasarnya berfungsi seperti ini:
- Siapkan: Templat pernyataan SQL dibuat dan dikirim ke database. Nilai-nilai tertentu dibiarkan tidak ditentukan, yang disebut parameter (berlabel "?"). Contoh: INSERT INTO MyGuests VALUES(?, ?, ?)
- Basis data mem-parsing, mengkompilasi, dan melakukan optimisasi kueri pada templat pernyataan SQL, dan menyimpan hasilnya tanpa menjalankannya
- Jalankan: Di lain waktu, aplikasi mengikat nilai ke parameter, dan database mengeksekusi pernyataan tersebut. Aplikasi dapat mengeksekusi pernyataan sebanyak yang diinginkan dengan nilai yang berbeda
Dibandingkan dengan mengeksekusi pernyataan SQL secara langsung, pernyataan yang disiapkan memiliki tiga keunggulan utama:
- Pernyataan yang disiapkan mengurangi waktu penguraian karena persiapan pada kueri dilakukan hanya sekali (walaupun pernyataan dijalankan beberapa kali)
- Parameter terikat meminimalkan bandwidth ke server karena Anda hanya perlu mengirim parameter setiap kali, dan bukan seluruh kueri
- Pernyataan yang telah disiapkan sangat berguna untuk melawan injeksi SQL, karena nilai parameter, yang ditransmisikan kemudian menggunakan protokol yang berbeda, tidak perlu diloloskan dengan benar. Jika templat pernyataan asli tidak berasal dari input eksternal, injeksi SQL tidak dapat terjadi.
Pernyataan yang Disiapkan di MySQLi
Contoh berikut menggunakan pernyataan yang disiapkan dan parameter terikat di MySQLi:
Contoh (MySQLi dengan Pernyataan yang Disiapkan)
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// prepare and bind
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);
// set parameters and execute
$firstname = "John";
$lastname = "Doe";
$email = "[email protected]";
$stmt->execute();
$firstname = "Mary";
$lastname = "Moe";
$email = "[email protected]";
$stmt->execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "[email protected]";
$stmt->execute();
echo "New records created successfully";
$stmt->close();
$conn->close();
?>
Baris kode untuk menjelaskan dari contoh di atas:
"INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"
Dalam SQL kami, kami menyisipkan tanda tanya (?) di mana kami ingin mengganti nilai integer, string, double atau blob.
Kemudian, lihat fungsi bind_param() :
$stmt->bind_param("sss", $firstname, $lastname, $email);
Fungsi ini mengikat parameter ke kueri SQL dan memberi tahu database apa parameternya. Argumen "sss" mencantumkan tipe data yang menjadi parameternya. Karakter s memberi tahu mysql bahwa parameternya adalah string.
Argumen mungkin salah satu dari empat jenis:
- i - bilangan bulat
- d - ganda
- s - string
- b - Gumpalan
Kita harus memiliki salah satu dari ini untuk setiap parameter.
Dengan memberi tahu mysql jenis data apa yang diharapkan, kami meminimalkan risiko injeksi SQL.
Catatan: Jika kita ingin menyisipkan data apa pun dari sumber eksternal (seperti input pengguna), sangat penting bahwa data dibersihkan dan divalidasi.
Pernyataan yang Disiapkan dalam PDO
Contoh berikut menggunakan pernyataan yang disiapkan dan parameter terikat di PDO:
Contoh (PDO dengan Pernyataan yang Disiapkan)
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// prepare sql and bind parameters
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email)
VALUES (:firstname, :lastname, :email)");
$stmt->bindParam(':firstname', $firstname);
$stmt->bindParam(':lastname', $lastname);
$stmt->bindParam(':email', $email);
// insert a row
$firstname = "John";
$lastname = "Doe";
$email = "[email protected]";
$stmt->execute();
// insert another row
$firstname = "Mary";
$lastname = "Moe";
$email = "[email protected]";
$stmt->execute();
// insert another row
$firstname = "Julie";
$lastname = "Dooley";
$email = "[email protected]";
$stmt->execute();
echo "New records created successfully";
} catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
$conn = null;
?>