0Pricing
PHP Academy · レッスン

プリペアドステートメントとバインド

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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. PDOでMySQLに接続する
  2. プリペアドステートメントとバインド
  3. PDOで結果を取得する
  4. PDOによるトランザクション
← PHP Academyに戻る