📢 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> | ||