ch04 12章中 4章目

ch04 — WHERE / プレースホルダ / prepare + execute

スライドで見る

この章を AI と学ぶ

💬 AI に聞く質問例 3 件
  1. 「ch04 — WHERE / プレースホルダ / prepare + execute」のつまずきやすいポイントを、初学者向けに3つ教えてください

    ChatGPT Claude Gemini

  2. 「ch04 — WHERE / プレースホルダ / prepare + execute」について、自分の手で試せる練習問題を3つ出してください (難易度を上げながら)

    ChatGPT Claude Gemini

  3. 「ch04 — WHERE / プレースホルダ / prepare + execute」を学んだ後、次に学ぶと良いトピックは何ですか?理由も教えてください

    ChatGPT Claude Gemini

概要

SELECT * FROM users は全件取れるが、実用では 「条件に合う行だけ」 が欲しい。これを担うのが WHERE で、SELECT * FROM users WHERE age >= 25 のように「列に対する条件」を書く。比較演算子 (= >= < !=)、論理結合 (AND OR)、あいまい検索 (LIKE 'A%') を組み合わせて絞り込む。

ここで最重要なのが、値を SQL に直接書かず、必ず ? プレースホルダを使う こと。"WHERE name = '$name'" のように文字列連結すると、入力に '; が混ざった瞬間に SQL が壊れる (= SQL インジェクションの入り口)。PHP では「SQL の を先に登録 → 値は後から 別ルート で渡す」という 2 段階で書く。これが prepareexecute の役割。

リズムは $stmt = $pdo->prepare("SELECT * FROM users WHERE age >= ?") で型紙を作り、$stmt->execute([25]) で値を埋め込み、$stmt->fetchAll() で結果を受ける。? は左から順に配列要素と対応。複数条件でも値の配列を渡すだけ。このリズムが INSERT / UPDATE / DELETE すべての基本形になる。

学習目標

  • WHERE 句で行を絞り込める
  • 値を埋め込むときは 必ず ? プレースホルダ を使う (SQL インジェクション対策の入口)
  • $pdo->prepare($sql)$stmt->execute([...])$stmt->fetchAll() の流れを書ける
  • 複数条件 (AND) と LIKE の基本を扱える

ドリル

no 内容
01 age = ? で特定年齢の名前を出力
02 age >= ? で 25 以上の人を出力
03 name LIKE ? AND age < ? で 2 条件検索

解説スライド 全 7 枚

右の ボタン キー(またはスワイプ)で次のスライドに進めます。 下の「縦表示」を開くと全スライドを一気に読めます。

  1. WHERE / プレースホルダ / prepare + execute

    Lesson 11 / Chapter 4

  2. WHERE で行を絞り込む

    SELECT name FROM users WHERE age >= 25 ORDER BY id;
    • WHERE 条件 を付けると、条件に合う 行だけ が返る
    • = / < / <= / > / >= / <> (≠) が使える
    • 文字列の 部分一致LIKE: name LIKE '太%' (「太」で始まる)
    • AND / OR で複数条件をつなげられる
  3. ⚠ やってはいけない: 文字列連結

    // ❌ 絶対にこう書かない
    $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 に混ぜるときは必ずプレースホルダ ? を使う

  4. ✅ 正しい書き方: プレースホルダ ?

    $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 インジェクションを防げる
  5. 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 個目が '太%'
  6. 複数条件 / 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 条件以上
    • ワイルドカード文字 (% / _) はプレースホルダ側ではなく、渡す値の側 に入れる
  7. このチャプターでできるようになること

    WHERE 句で行を絞れる ✅ 値を埋め込むときは ? プレースホルダを使うとわかっている ✅ prepare()execute([...])fetchAll() の流れを書ける ✅ 複数条件 (AND) と LIKE を組み合わせられる

    → ドリルへ

1 / 7
📜 スライドを全部一気に読む(縦表示)

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 を組み合わせられる

→ ドリルへ

この章で取り組む 演習問題の流れ (3ステップ)
  1. 01 ドリル 01 — `age = ?` で特定年齢の名前を出力 README.md starter.php answer.php
  2. 02 ドリル 02 — `age >= ?` で 25 以上の人を出力 README.md starter.php answer.php
  3. 03 ドリル 03 — `name LIKE ? AND age < ?` で 2 条件検索 README.md starter.php answer.php

演習問題の詳細

この章の演習問題の内容を読めます。実際に手元で解くには教材リポジトリを clone してください。

ドリル 01 — `age = ?` で特定年齢の名前を出力

問題

users テーブル (id, name, age) には次の 3 行が入っています。

id name age
1 太郎 20
2 花子 25
3 次郎 30

age がちょうど 25 の人の名前 を、id 昇順で 1 行ずつ出力してください。

期待される出力:

花子

必須ルール

  • 値を SQL に 文字列連結してはいけません
  • ? プレースホルダ + prepare() + execute() を使うこと

ヒント

$stmt = $pdo->prepare('SELECT name FROM users WHERE age = ? ORDER BY id');
$stmt->execute([25]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

🧪 ブラウザで試す

スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。

PHP ランタイム未読込

          

        

ドリル 02 — `age >= ?` で 25 以上の人を出力

問題

users テーブル (id, name, age) には次の 3 行が入っています。

id name age
1 太郎 20
2 花子 25
3 次郎 30

age が 25 以上の人の名前id 昇順で 1 行ずつ出力してください。

期待される出力:

花子
次郎

必須ルール

  • 値を SQL に 文字列連結してはいけません
  • ? プレースホルダ + prepare() + execute() を使うこと

ヒント

$stmt = $pdo->prepare('SELECT name FROM users WHERE age >= ? ORDER BY id');
$stmt->execute([25]);

🧪 ブラウザで試す

スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。

PHP ランタイム未読込

          

        

ドリル 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 のワイルドカード %渡す値 の側に入れる (例: '太%')

ヒント

$sql = 'SELECT name FROM users WHERE name LIKE ? AND age < ? ORDER BY id';
$stmt = $pdo->prepare($sql);
$stmt->execute(['太%', 30]);

🧪 ブラウザで試す

スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。

PHP ランタイム未読込

          

        

演習問題(3問)

  1. ドリル 01 — `age = ?` で特定年齢の名前を出力

    README.md starter.php answer.php

  2. ドリル 02 — `age >= ?` で 25 以上の人を出力

    README.md starter.php answer.php

  3. ドリル 03 — `name LIKE ? AND age < ?` で 2 条件検索

    README.md starter.php answer.php

サイト内で問題文・雛形・解答例を確認できます。実際に手元で解くには教材リポジトリを clone してください。

完了にすると進捗に反映されます