Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

PHP辞典

  1. トップページ
  2. PHP辞典
  3. PDO::prepare() / execute()

PDO::prepare() / execute()対応: PHP 5(2004)

SQL文をプリペアドステートメントとして準備し、パラメータをバインドして安全に実行します。SQLインジェクション攻撃を防ぐために、ユーザー入力を含むSQLでは必ずプリペアドステートメントを使用してください。

構文
// SQL文を準備します。
$stmt = $pdo->prepare($sql);

// プリペアドステートメントを実行します。
$stmt->execute($params);

// パラメータを名前で紐付けます。
$stmt->bindParam($param, $variable, $type);

// パラメータに値を直接紐付けます。
$stmt->bindValue($param, $value, $type);
メソッド一覧
メソッド概要
PDO::prepare($sql)SQL文をプリペアドステートメントとして準備します。プレースホルダーには『?』または『:name』を使用します。
PDOStatement::execute($params)プリペアドステートメントを実行します。引数にパラメータの配列を渡すことで値をバインドできます。
PDOStatement::bindParam($param, &$var, $type)パラメータを変数への参照で紐付けます。『execute()』実行時点の変数の値が使われます。
PDOStatement::bindValue($param, $value, $type)パラメータに値を直接紐付けます。呼び出し時点の値が固定されます。
パラメータの型定数
定数概要
PDO::PARAM_STR文字列型としてバインドします。デフォルトの型です。
PDO::PARAM_INT整数型としてバインドします。
PDO::PARAM_BOOL真偽値型としてバインドします。
PDO::PARAM_NULLNULL型としてバインドします。
サンプルコード
<?php
// 名前付きプレースホルダーでSELECT文を実行します。
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute([':email' => 'user@example.com']);
$user = $stmt->fetch();
echo $user['name']; // 該当ユーザーの名前が出力されます。

// 疑問符プレースホルダーを使用する方法です。
$stmt = $pdo->prepare("SELECT * FROM users WHERE age > ? AND city = ?");
$stmt->execute([20, '東京']);
$users = $stmt->fetchAll();

// INSERT文を実行します。
$stmt = $pdo->prepare("INSERT INTO users (name, email, age) VALUES (:name, :email, :age)");
$stmt->execute([
	':name' => '山田太郎',
	':email' => 'yamada@example.com',
	':age' => 30
]);
$newId = $pdo->lastInsertId(); // 挿入された行のIDを取得できます。
echo "登録ID: " . $newId;

// UPDATE文を実行します。
$stmt = $pdo->prepare("UPDATE users SET name = :name WHERE id = :id");
$stmt->execute([':name' => '山田次郎', ':id' => 1]);
echo $stmt->rowCount() . "件更新しました。"; // 更新された行数が出力されます。

// DELETE文を実行します。
$stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");
$stmt->execute([':id' => 5]);

// bindValue() で型を明示的に指定します。
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id AND active = :active");
$stmt->bindValue(':id', 1, PDO::PARAM_INT);
$stmt->bindValue(':active', true, PDO::PARAM_BOOL);
$stmt->execute();

// bindParam() はループ処理に便利です。変数への参照を保持します。
$stmt = $pdo->prepare("INSERT INTO logs (message) VALUES (:message)");
$stmt->bindParam(':message', $msg, PDO::PARAM_STR);
$messages = ['ログイン', 'ページ閲覧', 'ログアウト'];
foreach ($messages as $msg) {
	$stmt->execute(); // 各ループでその時点の $msg の値が使われます。
}

// LIKE検索でプレースホルダーを使います。
$keyword = '山田';
$stmt = $pdo->prepare("SELECT * FROM users WHERE name LIKE :keyword");
$stmt->execute([':keyword' => '%' . $keyword . '%']);
概要

プリペアドステートメントは、SQL文とデータを分離して処理する仕組みです。ユーザー入力をSQL文に直接埋め込むのは極めて危険です。必ず『PDO::prepare()』と『execute()』を使用して、プレースホルダー経由でパラメータを渡してください。これによりSQLインジェクション攻撃を根本的に防止できます。

『bindValue()』は呼び出し時点の値が固定され、『bindParam()』は『execute()』実行時点の変数の値が使われます。ループ内で同じステートメントを繰り返し実行する場合は『bindParam()』が便利です。単純なパラメータの受け渡しであれば、『execute()』の引数に配列を渡す方法が最も簡潔に書けます。

データベースへの接続は『new PDO()』で行い、結果の取得は『fetch() / fetchAll()』を使用してください。複数のSQL文をまとめて実行する場合は『トランザクション』の使用を検討してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。