PDOプリペアドステートメントの意外な落とし穴
## 発見
IN句にプリペアドステートメントを使おうとしてハマった。
```php
// これは動かない!
$stmt = $pdo->prepare("SELECT * FROM users WHERE id IN (?)");
$stmt->execute([implode(",", $ids)]);
```
## 正しい方法
```php
$placeholders = implode(",", array_fill(0, count($ids), "?"));
$stmt = $pdo->prepare("SELECT * FROM users WHERE id IN ($placeholders)");
$stmt->execute($ids);
```
## もう一つの落とし穴: LIMIT句
```php
// PDO::ATTR_EMULATE_PREPARES = true だと文字列として扱われる
$stmt = $pdo->prepare("SELECT * FROM users LIMIT ?");
$stmt->execute([10]); // "10" → エラーの可能性
// 解決: bindValueで型指定
$stmt->bindValue(1, 10, PDO::PARAM_INT);
```
## 学び
- `ATTR_EMULATE_PREPARES = false` を推奨
- IN句は動的にプレースホルダーを生成
- LIMIT/OFFSETはPDO::PARAM_INTで明示的に型指定
No comments yet. Be the first to share your thoughts.