PHPチュートリアル

PHPホーム PHPイントロ PHPインストール PHP構文 PHPコメント PHP変数 PHPエコー/印刷 PHPデータ型 PHP文字列 PHP番号 PHP数学 PHP定数 PHP演算子 PHP If ... Else ... Elseif PHPスイッチ PHPループ PHP関数 PHP配列 PHPスーパーグローバル PHP正規表現

PHPフォーム

PHPフォーム処理 PHPフォームの検証 PHPフォームが必要 PHPフォームのURL / Eメール PHPフォームの完了

PHP Advanced

PHPの日付と時刻 PHPインクルード PHPファイルの処理 PHPファイルのオープン/読み取り PHPファイルの作成/書き込み PHPファイルのアップロード PHPクッキー PHPセッション PHPフィルター PHPフィルターアドバンスト PHPコールバック関数 PHP JSON PHPの例外

PHPOOP _

PHPOOPとは PHPクラス/オブジェクト PHPコンストラクター PHPデストラクタ PHPアクセス修飾子 PHPの継承 PHP定数 PHP抽象クラス PHPインターフェース PHPの特性 PHP静的メソッド PHPの静的プロパティ PHP名前空間 PHPIterables

MySQLデータベース

MySQLデータベース MySQLコネクト MySQL Create DB MySQLテーブルの作成 MySQLの挿入データ MySQLは最後のIDを取得します MySQL Insert Multiple MySQLを準備しました MySQL Select Data MySQL Where MySQL Order By MySQLデータの削除 MySQLアップデートデータ MySQL制限データ

PHP XML

PHPXMLパーサー PHPSimpleXMLパーサー PHPSimpleXML-取得 PHP XMLExpat PHP XML DOM

PHP -AJAX

AJAXイントロ AJAX PHP AJAXデータベース AJAX XML AJAXライブ検索 AJAXポール

PHPの

PHPの例 PHPコンパイラ PHPクイズ PHP演習 PHP証明書

PHPリファレンス

PHPの概要 PHP配列 PHPカレンダー PHPの日付 PHPディレクトリ PHPエラー PHP例外 PHPファイルシステム PHPフィルター PHP FTP PHP JSON PHPキーワード PHP Libxml PHPメール PHP数学 PHPその他 PHP MySQLi PHPネットワーク PHP出力制御 PHP正規表現 PHP SimpleXML PHPストリーム PHP文字列 PHP変数の処理 PHPXMLパーサー PHP Zip PHPタイムゾーン

PHPMySQLプリペアドステートメント


プリペアドステートメントは、SQLインジェクションに対して非常に役立ちます。


プリペアドステートメントとバインドされたパラメータ

プリペアドステートメントは、同じ(または類似の)SQLステートメントを高効率で繰り返し実行するために使用される機能です。

プリペアドステートメントは基本的に次のように機能します。

  1. 準備:SQLステートメントテンプレートが作成され、データベースに送信されます。パラメータと呼ばれる特定の値は指定されていません(「?」というラベルが付いています)。例:INSERT INTO MyGuests VALUES(?、?、?)
  2. データベースは、SQLステートメントテンプレートのクエリ最適化を解析、コンパイル、および実行し、結果を実行せずに保存します
  3. 実行:後で、アプリケーションが値をパラメーターにバインドし、データベースがステートメントを実行します。アプリケーションは、さまざまな値を使用して、ステートメントを何度でも実行できます。

SQLステートメントを直接実行する場合と比較して、プリペアドステートメントには3つの主な利点があります。

  • プリペアドステートメントは、クエリの準備が1回だけ行われるため、解析時間を短縮します(ただし、ステートメントは複数回実行されます)。
  • バインドされたパラメーターは、クエリ全体ではなく、毎回パラメーターのみを送信する必要があるため、サーバーへの帯域幅を最小限に抑えます。
  • プリペアドステートメントは、後で別のプロトコルを使用して送信されるパラメータ値を正しくエスケープする必要がないため、SQLインジェクションに対して非常に役立ちます。元のステートメントテンプレートが外部入力から派生していない場合、SQLインジェクションは発生しません。

MySQLiで準備されたステートメント

次の例では、MySQLiでプリペアドステートメントとバインドされたパラメータを使用しています。

例(プリペアドステートメントを使用した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 = "[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();
?>

上記の例から説明するコード行:

"INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"

SQLでは、整数、文字列、double、またはblob値に代入する疑問符(?)を挿入します。

次に、bind_param()関数を見てください。

$stmt->bind_param("sss", $firstname, $lastname, $email);

この関数は、パラメーターをSQLクエリにバインドし、データベースにパラメーターが何であるかを通知します。「sss」引数は、パラメーターであるデータのタイプをリストします。s文字は、パラメータが文字列であることをmysqlに通知します。

引数は、次の4つのタイプのいずれかになります。

  • i-整数
  • d-ダブル
  • s-文字列
  • b-BLOB

パラメータごとにこれらの1つが必要です。

予想されるデータのタイプをmysqlに通知することで、SQLインジェクションのリスクを最小限に抑えます。

注:外部ソース(ユーザー入力など)からデータを挿入する場合は、データをサニタイズして検証することが非常に重要です。



PDOで準備されたステートメント

次の例では、PDOでプリペアドステートメントとバインドされたパラメーターを使用しています。

例(プリペアドステートメントを使用した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 = "[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;
?>