PHP Prepared 文

❮ 前章へ 次章へ ❯

Prepared 文は、SQLインジェクションに対して非常に役立ちます。


Prepared 文と Bound パラメータ

Prepared 文は、同じ(または類似の)SQL文を高効率で繰り返し実行するために使用する機能です。

Prepared 文は基本的には次のように動作します:

  1. Prepare: SQL文のテンプレートを作成し、データベースに送信します。特定の値は、パラメータ("?"記号)と呼ばれる未指定のままにします。 例:INSERT INTOMyGuests VALUES(?, ?, ?)
  2. データベースは、SQL文テンプレートをパース、コンパイル、およびクエリの最適化を行い、それを実行せずに結果を格納します
  3. Execute: その後、アプリケーションは値をパラメータにバインドして、データベースは文を実行します。 アプリケーションは、異なる値で必要な回数だけ文を実行することができます

SQL文を直接実行する場合と比較して、Prepared 文には主に次の3つの利点があります:


MySQLiにおけるPrepared文

次の例では、MySQLiで prepared 文と bound パラメータを使用しています

例(Prepared文を使用したMySQLi)

<?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文

次の例では、PDOでprepared文とboundパラメータを使用しています:

例(Prepared文を使用したPDO)

<?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;
?>


❮ 前章へ 次章へ ❯