WHERE / プレースホルダ / prepare + execute
テクノロジ系 / db (PDO / SQL / マルチDB)
WHERE / プレースホルダ / prepare + execute
Lesson 11 / Chapter 4
WHERE で行を絞り込む
SELECT name FROM users WHERE age >= 25 ORDER BY id;
WHERE 条件を付けると、条件に合う 行だけ が返る=/</<=/>/>=/<>(≠) が使える- 文字列の 部分一致 は
LIKE:name LIKE '太%'(「太」で始まる) AND/ORで複数条件をつなげられる
⚠ やってはいけない: 文字列連結
// ❌ 絶対にこう書かない $age = $_GET['age']; $sql = "SELECT name FROM users WHERE age = $age"; $pdo->query($sql);
ユーザー入力をそのまま SQL に連結すると、外から SQL を 書き換えられる (SQL インジェクション)。
例: $age に 0 OR 1=1 を入れられると WHERE age = 0 OR 1=1 になり、全件返ってしまう。
→ 値を SQL に混ぜるときは必ずプレースホルダ ? を使う
✅ 正しい書き方: プレースホルダ ?
$sql = 'SELECT name FROM users WHERE age = ? ORDER BY id';
$stmt = $pdo->prepare($sql);
$stmt->execute([25]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
echo $row['name'] . "\n";
}- SQL の中に値を書かず
?(プレースホルダ) を置く prepare()で SQL を準備、execute([...])で値を渡す- 値は PDO 側で安全に処理される → SQL インジェクションを防げる
prepare → execute → fetch の流れ
// 1. SQL に ? を置いて prepare
$stmt = $pdo->prepare('SELECT name FROM users WHERE age = ?');
// 2. execute に値を配列で渡す (? の数と配列の要素数を一致させる)
$stmt->execute([25]);
// 3. 結果を取り出す
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);?が複数あるときは配列の 順番 がそのまま対応するexecute([25, '太%'])なら 1 個目の?が 25、2 個目が'太%'
複数条件 / LIKE
$sql = 'SELECT name FROM users
WHERE name LIKE ? AND age < ?
ORDER BY id';
$stmt = $pdo->prepare($sql);
$stmt->execute(['太%', 30]);LIKE '太%'… 「太」で始まる名前 (%は 0 文字以上の任意文字列)ANDでつなげれば 2 条件以上- ワイルドカード文字 (
%/_) はプレースホルダ側ではなく、渡す値の側 に入れる
このチャプターでできるようになること
✅ WHERE 句で行を絞れる
✅ 値を埋め込むときは ? プレースホルダを使うとわかっている
✅ prepare() → execute([...]) → fetchAll() の流れを書ける
✅ 複数条件 (AND) と LIKE を組み合わせられる
→ ドリルへ
考えてみよう
既定では正解・不正解の判定はしません。自分のペースで「答えを見る」を。採点してほしい場合だけ「採点してほしい」を押してください。
ドリル 01 — age = ? で特定年齢の名前を出力
問題
users テーブル (id, name, age) には次の 3 行が入っています。
| id | name | age |
|---|---|---|
| 1 | 太郎 | 20 |
| 2 | 花子 | 25 |
| 3 | 次郎 | 30 |
age がちょうど 25 の人の名前 を、id 昇順で 1 行ずつ出力してください。
期待される出力:
花子
必須ルール
- 値を SQL に 文字列連結してはいけません
?プレースホルダ +prepare()+execute()を使うこと
採点
php scripts/grade.php topics/db/ch04-select-where/drill/01-where-equals/
ヒント
$stmt = $pdo->prepare('SELECT name FROM users WHERE age = ? ORDER BY id');
$stmt->execute([25]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);ドリル 02 — age >= ? で 25 以上の人を出力
問題
users テーブル (id, name, age) には次の 3 行が入っています。
| id | name | age |
|---|---|---|
| 1 | 太郎 | 20 |
| 2 | 花子 | 25 |
| 3 | 次郎 | 30 |
age が 25 以上の人の名前 を id 昇順で 1 行ずつ出力してください。
期待される出力:
花子 次郎
必須ルール
- 値を SQL に 文字列連結してはいけません
?プレースホルダ +prepare()+execute()を使うこと
採点
php scripts/grade.php topics/db/ch04-select-where/drill/02-where-greater/
ヒント
$stmt = $pdo->prepare('SELECT name FROM users WHERE age >= ? ORDER BY id');
$stmt->execute([25]);ドリル 03 — name LIKE ? AND age < ? で 2 条件検索
問題
users テーブル (id, name, age) には次の 4 行が入っています。
| id | name | age |
|---|---|---|
| 1 | 太郎 | 20 |
| 2 | 花子 | 25 |
| 3 | 次郎 | 30 |
| 4 | 太田 | 22 |
次の 2 条件を両方 満たす人の名前を、id 昇順で 1 行ずつ出力してください。
nameが「太」で始まる (LIKE '太%')ageが 30 より小さい (age < 30)
期待される出力:
太郎 太田
必須ルール
- 値を SQL に 文字列連結してはいけません
?プレースホルダを 2 つ使い、execute([...])に 2 個の値を渡すことLIKEのワイルドカード%は 渡す値 の側に入れる (例:'太%')
採点
php scripts/grade.php topics/db/ch04-select-where/drill/03-multiple-params/
ヒント
$sql = 'SELECT name FROM users WHERE name LIKE ? AND age < ? ORDER BY id'; $stmt = $pdo->prepare($sql); $stmt->execute(['太%', 30]);