疑問
疑問①
なぜ一覧取得(SELECT)では bindValue() を使うのに、
$sql = 'SELECT * FROM articles ORDER BY created_at DESC LIMIT :limit OFFSET :start';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->bindValue(':start', $start, PDO::PARAM_INT);
$stmt->execute();
疑問②
なぜ保存処理(INSERT / store)では bindValue() を使っていないのか?
$sql = 'INSERT INTO articles (article_uuid, name)
VALUES (:article_uuid, :name)';
$stmt = $pdo->prepare($sql);
$stmt->execute([
':article_uuid' => $article_uuid,
':name' => $name,
]);
結論
bindValue を「使っていない」のではなく、
execute() の中でまとめて使っているだけ。
① bindValue の役割を整理する
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
これは、
・SQLのプレースホルダに
・安全に値を渡す
・型を固定する
ための処理。
② SELECT(一覧取得)で bindValue を使う理由
ポイント:LIMIT / OFFSET は「整数限定」
LIMIT :limit OFFSET :start
・文字列はNG
・不正な値は、SQLエラー
・DB依存の事故が起きやすい
だから ↓
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->bindValue(':start', $start, PDO::PARAM_INT);
型を明示的に INT に固定する必要がある
③ INSERT(store)で bindValue を書いていない理由
実はこの1行が全部やっている
$stmt->execute([
':article_uuid' => $article_uuid,
':name' => $name,
]);
これは内部的に ↓ と同じ。
$stmt->bindValue(':article_uuid', $article_uuid);
$stmt->bindValue(':name', $name);
$stmt->execute();
bindValue を省略した書き方(短縮記法)
④ なぜ store では execute(配列) がよく使われる?
・プレースホルダが多い
・文字列中心
・型指定が不要
・コードが短くて読みやすい
→ INSERT / UPDATE では定番
⑤ 使い分けの判断基準
| bindValue | execute(配列) |
|---|---|
| LIMIT / OFFSET | INSERT / UPDATE |
| 数値型が厳密 | 文字列中心 |
| 型を PDO::PARAM_INT で固定したい | プレースホルダが多い |
| ページネーション | シンプルに書きたい |
⑥ 両者の関係を一言で
bindValue は「値を渡す処理」
execute(配列) は「bindValue をまとめてやってくれる書き方」