採点されません。匿名です。 間違えることは学習の一部です。読むだけでもかまいません。

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 インジェクション)。

例: $age0 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 行が入っています。

idnameage
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 行が入っています。

idnameage
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 行が入っています。

idnameage
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]);