📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

 
(同じ利用者による、間の1版が非表示)
645行目: 645行目:
<br>
<br>
プリペアドステートメントは、データベースの種類や機能に関わらず同じ仕組みで データベースへのアクセスができる。<br>
プリペアドステートメントは、データベースの種類や機能に関わらず同じ仕組みで データベースへのアクセスができる。<br>
<br><br>
== プリペアドステートメントの種類 ==
==== bindValueメソッド (値渡し) ====
* メリット
*: バインドした後に元の変数が変更されても影響を受けない。
*: 直接リテラル値をバインドできる。
*: メモリ効率が良い。 (参照を保持しない)
* デメリット
*: ループ内で変数を変更して再実行する場合は、その都度、bindValueメソッドが必要となる。
<br>
<syntaxhighlight lang="php">
$value = 100;
$stmt->bindValue(1, $value, PDO::PARAM_INT);
$value = 200;      // この変更はSQLに影響しない
$stmt->execute();  // 100 が使用される
</syntaxhighlight>
<br>
==== bindParamメソッド (参照渡し) ====
* メリット
*: 変数の参照を保持するので、値を変更して再実行が容易
*: ストアドプロシージャのOUTパラメータで使用可能
* デメリット
*: リテラル値を直接バインドできない。
*: メモリを若干多く使用する。 (参照を保持するため)
<br>
<syntaxhighlight lang="php">
$value = 100;
$stmt->bindParam(1, $value, PDO::PARAM_INT);
$value = 200;      // この変更がSQLに反映される
$stmt->execute();  // 200 が使用される
</syntaxhighlight>
<br>
==== executeメソッドで直接記述 ====
* メリット
*: コードが簡潔
*: 1回のみ使用する場合は効率的
*: <br>
* デメリット
*: 変数の値を後から変更して再実行する場合は、その都度配列を作る必要がある。
*: 参照渡しができない。
<br>
<syntaxhighlight lang="php">
$stmt = $pdo->prepare("UPDATE student SET id = ?, name = ?, grade = ? WHERE id = ?");
$stmt->execute([$id, $name, $grade, $old_id]);  // シンプル!
## 1回限りのクエリの場合、executeメソッド
$stmt->execute([$id, $name, $grade]);
</syntaxhighlight>
<br>
==== 使い分け ====
<syntaxhighlight lang="php">
# 使い分け
## 一般的なケースでは、bindValueメソッドを使用
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bindValue(1, $id, PDO::PARAM_INT);
$stmt->execute();
## 以下に示す場合は、bindParamメソッドを使用
## ループ内で値を変更しながら実行する場合
## ループ内で変数を変更しながら再実行する場合
## ストアドプロシージャのOUTパラメータを使用する場合
## 特別な理由で参照渡しが必要な場合
$stmt = $pdo->prepare("INSERT INTO logs (user_id, action) VALUES (?, ?)");
$stmt->bindParam(1, $user_id, PDO::PARAM_INT);
$stmt->bindParam(2, $action, PDO::PARAM_STR);
foreach($actions as $action) {
    $stmt->execute();  // $actionの値が自動的に使用される
}
</syntaxhighlight>
<br>
<u>セキュリティが重要な場合は、型を明示的に指定できるbindValueメソッド、または、bindParamメソッドを使用する。</u><br>
<br>
<u>※注意</u><br>
<u>ただし、実務では一貫性を保つため、特別な理由がない限りどちらか一方に統一することが推奨される。</u><br>
<br><br>
<br><br>