プリペアドステートメントとバインド
prepare、bindParam、executeを使ってSQLインジェクションを防ぎます
「プリペアドステートメントとバインド」はCoddyKit上の無料PHP Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPHP Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 PHP Academyコースには全4レッスンが含まれています。
プリペアドステートメントを使う理由
プリペアドステートメントは、SQLの構造とデータを分離します。ユーザー入力は常に値として扱われ、SQLコードとして扱われることはありません。そのため、SQLインジェクションを防止できます。
prepare()とexecute()
基本的な流れは、プレースホルダーを使ってprepareし、その後、値を指定してexecuteすることです。
<?php
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$_POST["email"]]);
$user = $stmt->fetch();名前付きプレースホルダー
特に同じ値が複数回登場する場合は、わかりやすさのために名前付きプレースホルダー(:name)を使用してください。
<?php
$stmt = $pdo->prepare(
"INSERT INTO users (name, email) VALUES (:name, :email)"
);
$stmt->execute([':name' => "Alice", ':email' => "alice@example.com"]);bindParamとbindValue
bindParamは変数を参照渡しでバインドし、executeの時点で値を読み取ります。bindValueは値をその場でバインドします。
<?php
$name = "Bob";
$stmt = $pdo->prepare("INSERT INTO users (name) VALUES (:name)");
$stmt->bindParam(":name", $name);
$name = "Carol";
$stmt->execute(); // inserts "Carol"bindValueの例
バインドした時点の値を固定したい場合は、bindValueを使用してください。
<?php
$stmt = $pdo->prepare("SELECT * FROM products WHERE price < :max");
$stmt->bindValue(":max", 50.00, PDO::PARAM_INT);
$stmt->execute();型定数
オプションの第3引数ではデータ型を指定します。PDO::PARAM_INT、PDO::PARAM_STR、PDO::PARAM_BOOL、PDO::PARAM_NULLを指定できます。
ステートメントの再実行
プリペアドステートメントは複数回実行できます。クエリはサーバー上で一度だけコンパイルされます。
<?php
$stmt = $pdo->prepare("INSERT INTO logs (msg) VALUES (:msg)");
foreach ($messages as $msg) {
$stmt->execute([':msg' => $msg]);
}rowCount()
INSERT、UPDATE、DELETEの後にrowCount()を呼び出すと、影響を受けた行数を取得できます。
<?php
$stmt = $pdo->prepare("DELETE FROM users WHERE active = 0");
$stmt->execute();
echo $stmt->rowCount()." users deleted";lastInsertId()
INSERTの後に$pdo->lastInsertId()を使うと、自動インクリメントされた主キーを取得できます。
<?php
$stmt = $pdo->prepare("INSERT INTO articles (title) VALUES (:t)");
$stmt->execute([':t' => "My Post"]);
$newId = $pdo->lastInsertId();ユーザー入力を連結しない
次のような処理は決して行わないでください。"SELECT * FROM users WHERE name = '".$name."'"。入力を「サニタイズ」した場合でも、必ずプレースホルダーを使用してください。
PDOStatementオブジェクト
prepare()は、execute()、fetch()、fetchAll()、bindParam()、bindValue()、rowCount()を備えたPDOStatementを返します。
まとめ
外部データを含むクエリでは、必ずプリペアドステートメントを使用してください。名前付きプレースホルダーを推奨します。即時に値をバインドする場合はbindValueを、ループ内でバインドする場合はbindParamを使用してください。
クイックチェック
bindParamはいつ値を読み取りますか。
よくある質問
「プリペアドステートメントとバインド」レッスンは無料ですか?
はい。「プリペアドステートメントとバインド」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、PHP Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 PHP Academyコースには全4レッスンが含まれています。
「プリペアドステートメントとバインド」で何を学びますか?
prepare、bindParam、executeを使ってSQLインジェクションを防ぎます ブラウザで直接実行するハンズオンコードでPHP Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
PHP Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのPHP Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「プリペアドステートメントとバインド」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このPHP Academyレッスンでコードを書いて実行できますか?
はい。すべてのPHP Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- PDOでMySQLに接続する
- プリペアドステートメントとバインド
- PDOで結果を取得する
- PDOによるトランザクション