Prepared 文は、SQLインジェクションに対して非常に役立ちます。
Prepared 文は、同じ(または類似の)SQL文を高効率で繰り返し実行するために使用する機能です。
Prepared 文は基本的には次のように動作します:
SQL文を直接実行する場合と比較して、Prepared 文には主に次の3つの利点があります:
次の例では、MySQLiで prepared 文と bound パラメータを使用しています
<?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 = "john@example.com";
$stmt->execute();
$firstname = "Mary";
$lastname = "Moe";
$email = "mary@example.com";
$stmt->execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "julie@example.com";
$stmt->execute();
echo "New records created successfully";
$stmt->close();
$conn->close();
?>
上の例のコード行の説明:
"INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"
このSQLでは、整数、文字列、倍精度、や BLOB 値の代わりに、疑問符(?)を挿入します
次に、bind_param()関数を見てください:
$stmt->bind_param("sss", $firstname, $lastname, $email);
この関数は、パラメータをSQLクエリにバインドし、パラメータが何であるかをデータベースに伝えます。 引数の"sss"は、パラメータで指定しているデータの種類をリストしたものです。 文字 s は、パラメータが文字列であることをmysqlに伝えるものです。
引数は、次の4つの型のいずれかです:
このパラメータの1つを、各パラメータに設定しなければなりません。
mysqlに、期待するデータの種類を指定することで、SQLインジェクションのリスクを最小限に抑えられます。
注:外部ソースからのデータ(ユーザ入力など)を挿入する場合は、データをサニタイズや検証することが非常に重要です。
次の例では、PDOでprepared文とboundパラメータを使用しています:
<?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 = "john@example.com";
$stmt->execute();
// insert another row
$firstname = "Mary";
$lastname = "Moe";
$email = "mary@example.com";
$stmt->execute();
// insert another row
$firstname = "Julie";
$lastname = "Dooley";
$email = "julie@example.com";
$stmt->execute();
echo "New records created successfully";
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
$conn = null;
?>