Apa Itu Pernyataan Prepared
Pernyataan prepared (juga dikenal sebagai pernyataan parameterized) hanyalah template query SQL yang berisi placeholder sebagai ganti nilai parameter aktual. Placeholder ini akan diganti dengan nilai aktual pada saat pelaksanaan pernyataan tersebut.
MySQLi mendukung penggunaan anonymous positional placeholder ( ? ), Seperti yang ditunjukkan di bawah ini:

Sementara, PDO mendukung anonymous positional placeholder ( ? ), Serta placeholder yang disebutkan. Placeholder bernama dimulai dengan titik dua ( : ) diikuti oleh pengenal, seperti ini:

Eksekusi pernyataan prepared terdiri dari dua tahap: prepare dan execute.
- Prepare —- Pada tahap prepare, pernyataan template SQL dibuat dan dikirim ke server database. Server mem-parsing pernyataan template, melakukan pemeriksaan sintaks dan optimasi query, dan menyimpannya untuk digunakan nanti.
- Execute —- Selama eksekusi, nilai-nilai parameter dikirim ke server. Server membuat pernyataan dari pernyataan template dan nilai-nilai ini untuk menjalankannya.
Pernyataan yang disiapkan sangat berguna, khususnya dalam situasi ketika kalian menjalankan pernyataan tertentu beberapa kali dengan nilai yang berbeda, misalnya, serangkaian pernyataan INSERT. Bagian berikut menjelaskan beberapa manfaat utama penggunaannya.
Keuntungan Menggunakan Pernyataan Prepared
Pernyataan prepared dapat mengeksekusi pernyataan yang sama berulang kali dengan efisiensi tinggi, karena pernyataan hanya diurai (parsed) sekali lagi, sementara itu dapat dieksekusi berkali-kali. Ini juga meminimalkan penggunaan bandwidth, karena pada setiap eksekusi hanya nilai placeholder yang perlu ditransmisikan ke server database bukan pernyataan SQL lengkapnya.
Pernyataan prepared juga memberikan perlindungan yang kuat terhadap injeksi SQL, karena nilai parameter tidak tertanam langsung di dalam string kueri SQL. Nilai parameter dikirim ke server database secara terpisah dari query menggunakan protokol yang berbeda dan dengan demikian tidak dapat mencampuri hal tersebut. Server menggunakan nilai-nilai ini secara langsung pada titik eksekusi, setelah template pernyataan diuraikan (parsed). Itu sebabnya mengapa pernyataan prepared tidak rentan terhadap error, dan karena hal tersebutlah maka pernyataan tersebut dianggap sebagai salah satu elemen paling penting dalam keamanan basis data.
Contoh berikut akan menunjukkan kepada kalian bagaimana pernyataan prepared benar-benar berfungsi:
<?php /* Attempt MySQL server connection. Assuming you are running MySQL server with default setting (user 'root' with no password) */ $link = mysqli_connect("localhost", "root", "", "demo"); // Check connection if($link === false){ die("ERROR: Could not connect. " . mysqli_connect_error()); } // Prepare an insert statement $sql = "INSERT INTO persons (first_name, last_name, email) VALUES (?, ?, ?)"; if($stmt = mysqli_prepare($link, $sql)){ // Bind variables to the prepared statement as parameters mysqli_stmt_bind_param($stmt, "sss", $first_name, $last_name, $email); /* Set the parameters values and execute the statement again to insert another row */ $first_name = "Hermione"; $last_name = "Granger"; $email = "hermionegranger@mail.com"; mysqli_stmt_execute($stmt); /* Set the parameters values and execute the statement to insert a row */ $first_name = "Ron"; $last_name = "Weasley"; $email = "ronweasley@mail.com"; mysqli_stmt_execute($stmt); echo "Records inserted successfully."; } else{ echo "ERROR: Could not prepare query: $sql. " . mysqli_error($link); } // Close statement mysqli_stmt_close($stmt); // Close connection mysqli_close($link); ?>
Seperti yang kalian lihat pada contoh di atas, kita telah menyiapkan pernyataan INSERT hanya sekali tetapi mengeksekusinya beberapa kali dengan melewati serangkaian parameter yang berbeda.
Penjelasan Kode (Procedural style)
Di dalam pernyataan SQL INSERT (baris no-12) dari contoh di atas, tanda tanya digunakan sebagai placeholder untuk nilai bidang first_name, last_name, email.
Fungsi mysqli_stmt_bind_param() (baris no-16) mengikat variabel ke placeholder ( ? ) Dalam template pernyataan SQL. Placeholder ( ? ) Akan digantikan oleh nilai aktual yang disimpan dalam variabel pada saat eksekusi. String definisi type yang disediakan sebagai argumen kedua yaitu string “sss” menentukan bahwa tipe data dari setiap variabel terikat adalah string.
String definisi tipe menentukan tipe data dari variabel bind terkait dan berisi satu atau lebih dari empat karakter berikut:
- b — binary (seperti gambar, file PDF, dll.)
- d — dobel (angka floating point)
- i — integer (bilangan bulat)
- s — string (teks)
Jumlah variabel mengikat dan jumlah karakter dalam tipe string definisi jenis harus cocok dengan jumlah placeholder dalam template pernyataan SQL.
Menggunakan Input yang Diterima melalui Form Web
Jika kalian ingat dari bab sebelumnya, kita telah membuat formulir HTML untuk memasukkan data ke dalam basis data. Di sini, kita akan memperluas contoh itu dengan menerapkan pernyataan prepared. Kalian bisa menggunakan formulir HTML yang sama untuk menguji contoh skrip insert berikut, tetapi pastikan kalian menggunakan nama file yang benar dalam atribut action dari formulir.
Berikut kode PHP yang diperbarui untuk memasukkan data. Jika kalian melihat contoh dengan cermat, kalian akan menemukan bahwa kita tidak menggunakan mysqli_real_escape_string() untuk keluar dari input pengguna, seperti yang telah kita lakukan pada contoh bab sebelumnya. Karena dalam pernyataan yang disiapkan, input pengguna tidak pernah diganti ke query string secara langsung, sehingga input tersebut tidak perlu diloloskan dengan benar.
<?php /* Attempt MySQL server connection. Assuming you are running MySQL server with default setting (user 'root' with no password) */ $link = mysqli_connect("localhost", "root", "", "demo"); // Check connection if($link === false){ die("ERROR: Could not connect. " . mysqli_connect_error()); } // Prepare an insert statement $sql = "INSERT INTO persons (first_name, last_name, email) VALUES (?, ?, ?)"; if($stmt = mysqli_prepare($link, $sql)){ // Bind variables to the prepared statement as parameters mysqli_stmt_bind_param($stmt, "sss", $first_name, $last_name, $email); // Set parameters $first_name = $_REQUEST['first_name']; $last_name = $_REQUEST['last_name']; $email = $_REQUEST['email']; // Attempt to execute the prepared statement if(mysqli_stmt_execute($stmt)){ echo "Records inserted successfully."; } else{ echo "ERROR: Could not execute query: $sql. " . mysqli_error($link); } } else{ echo "ERROR: Could not prepare query: $sql. " . mysqli_error($link); } // Close statement mysqli_stmt_close($stmt); // Close connection mysqli_close($link); ?>