ch03 12章中 3章目

ch03 — SELECT 基本 / fetchAll / ループ

スライドで見る

この章を AI と学ぶ

💬 AI に聞く質問例 3 件
  1. 「ch03 — SELECT 基本 / fetchAll / ループ」のつまずきやすいポイントを、初学者向けに3つ教えてください

    ChatGPT Claude Gemini

  2. 「ch03 — SELECT 基本 / fetchAll / ループ」について、自分の手で試せる練習問題を3つ出してください (難易度を上げながら)

    ChatGPT Claude Gemini

  3. 「ch03 — SELECT 基本 / fetchAll / ループ」を学んだ後、次に学ぶと良いトピックは何ですか?理由も教えてください

    ChatGPT Claude Gemini

概要

接続できたら、まずやりたいのは 「テーブルからデータを取り出す」 こと。これを担う SQL が SELECT で、基本形は SELECT * FROM users のように「どの列を・どのテーブルから」を書くだけ。* は全列、SELECT id, name FROM users のように 列を絞る 書き方も覚えておく (取りすぎない方が速い)。

PHP 側では $pdo->query("SELECT ...") で SQL を投げて結果セットを受け取る。行の取り出しは foreach ($pdo->query(...) as $row)1 行ずつ回す か、$stmt->fetchAll()配列にまとめて受け取る の 2 パターン。件数が少ないなら fetchAll()、何万件なら foreach でストリーミング。

取り出された $row連想配列 で、$row['id'] / $row['name'] のように列名でアクセスする。値は基本すべて文字列で来るので、数値計算したいときは (int)$row['age'] のようにキャストする。「SQL を 1 つ書いて結果を foreach で回す」基本リズムを身体に通す。

学習目標

  • SELECT で行を取り出すコードを書ける
  • foreach ($pdo->query(...) as $row) で 1 行ずつ処理できる
  • fetchAll() で全行を配列にまとめて取れる
  • 行は連想配列 ($row['name']) としてアクセスできる

ドリル

no 内容
01 users を全件 SELECT して id: name 形式で出力
02 COUNT(*) で件数を出力
03 name 列だけ取り出し、改行区切りで出力

解説スライド 全 7 枚

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

  1. SELECT で行を取り出す

    Lesson 11 / Chapter 3

  2. SELECT は「テーブルから行を取り出す」命令

    SELECT id, name FROM users ORDER BY id;
    • SELECT 列名取り出したい列 を指定
    • FROM テーブル名どのテーブルから
    • ORDER BY 列名並び順 を固定 (順序を保証したいときは必ず付ける)
    • * を書くと全列 (SELECT * FROM users)
  3. PHP からは $pdo->query() で実行

    <?php
    $pdo = new PDO('sqlite:' . getenv('DOJO_DB_PATH'));
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $pdo->query('SELECT id, name FROM users ORDER BY id');
    • $pdo->query($sql) に SQL 文字列を渡すと、結果が PDOStatement で返る
    • query()値を埋め込まない固定 SQL 専用。ユーザー入力を混ぜるときは prepare (ch04)
  4. foreach で 1 行ずつ取り出す

    foreach ($pdo->query('SELECT id, name FROM users ORDER BY id') as $row) {
        echo $row['id'] . ': ' . $row['name'] . "\n";
    }

    実行結果:

    1: 太郎
    2: 花子
    3: 次郎
    • 1 行が連想配列で渡ってくる: $row['id'] / $row['name']
    • 行数が多くても メモリに全部載せずに済む (1 行ずつ処理)
  5. fetchAll() で全行を 1 つの配列に

    $stmt = $pdo->query('SELECT id, name FROM users ORDER BY id');
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    // $rows は配列の配列
    // [
    //   ['id' => 1, 'name' => '太郎'],
    //   ['id' => 2, 'name' => '花子'],
    //   ['id' => 3, 'name' => '次郎'],
    // ]
    
    foreach ($rows as $row) {
        echo $row['name'] . "\n";
    }
    • 後から件数を数えたい (count($rows)) / 並べ替えたいときは fetchAll の方が楽
    • ただし 全行メモリに載る ので、大量データなら foreach で 1 行ずつの方が安全
  6. COUNT(*) で件数だけ取る

    $stmt = $pdo->query('SELECT COUNT(*) AS cnt FROM users');
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    echo $row['cnt'] . "\n";   // 3
    • 1 行 1 列だけ返ってくるパターン
    • fetch() は 1 行だけ取り出すメソッド
    • AS cnt で列に名前を付けると $row['cnt'] で取れて読みやすい
  7. このチャプターでできるようになること

    SELECT 列 FROM テーブル ORDER BY 列 を書ける ✅ $pdo->query() で SELECT を実行できる ✅ foreach で 1 行ずつ処理できる ✅ fetchAll(PDO::FETCH_ASSOC) で全行を配列にできる ✅ 行は連想配列 ($row['列名']) でアクセスする

    → ドリルへ

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

Lesson 11 / Chapter 3


SELECT は「テーブルから行を取り出す」命令

SELECT id, name FROM users ORDER BY id;
  • SELECT 列名取り出したい列 を指定
  • FROM テーブル名どのテーブルから
  • ORDER BY 列名並び順 を固定 (順序を保証したいときは必ず付ける)
  • * を書くと全列 (SELECT * FROM users)

PHP からは $pdo->query() で実行

<?php
$pdo = new PDO('sqlite:' . getenv('DOJO_DB_PATH'));
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmt = $pdo->query('SELECT id, name FROM users ORDER BY id');
  • $pdo->query($sql) に SQL 文字列を渡すと、結果が PDOStatement で返る
  • query()値を埋め込まない固定 SQL 専用。ユーザー入力を混ぜるときは prepare (ch04)

foreach で 1 行ずつ取り出す

foreach ($pdo->query('SELECT id, name FROM users ORDER BY id') as $row) {
    echo $row['id'] . ': ' . $row['name'] . "\n";
}

実行結果:

1: 太郎
2: 花子
3: 次郎
  • 1 行が連想配列で渡ってくる: $row['id'] / $row['name']
  • 行数が多くても メモリに全部載せずに済む (1 行ずつ処理)

fetchAll() で全行を 1 つの配列に

$stmt = $pdo->query('SELECT id, name FROM users ORDER BY id');
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

// $rows は配列の配列
// [
//   ['id' => 1, 'name' => '太郎'],
//   ['id' => 2, 'name' => '花子'],
//   ['id' => 3, 'name' => '次郎'],
// ]

foreach ($rows as $row) {
    echo $row['name'] . "\n";
}
  • 後から件数を数えたい (count($rows)) / 並べ替えたいときは fetchAll の方が楽
  • ただし 全行メモリに載る ので、大量データなら foreach で 1 行ずつの方が安全

COUNT(*) で件数だけ取る

$stmt = $pdo->query('SELECT COUNT(*) AS cnt FROM users');
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo $row['cnt'] . "\n";   // 3
  • 1 行 1 列だけ返ってくるパターン
  • fetch() は 1 行だけ取り出すメソッド
  • AS cnt で列に名前を付けると $row['cnt'] で取れて読みやすい

このチャプターでできるようになること

SELECT 列 FROM テーブル ORDER BY 列 を書ける ✅ $pdo->query() で SELECT を実行できる ✅ foreach で 1 行ずつ処理できる ✅ fetchAll(PDO::FETCH_ASSOC) で全行を配列にできる ✅ 行は連想配列 ($row['列名']) でアクセスする

→ ドリルへ

この章で取り組む 演習問題の流れ (3ステップ)
  1. 01 ドリル 01 — 全件 SELECT して "id: name" 形式で出力 README.md starter.php answer.php
  2. 02 ドリル 02 — 件数を出力 README.md starter.php answer.php
  3. 03 ドリル 03 — name 列だけを取り出して改行区切りで出力 README.md starter.php answer.php

演習問題の詳細

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

ドリル 01 — 全件 SELECT して "id: name" 形式で出力

問題

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

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

id の昇順で全件 SELECT し、各行を id: name の形式 (id と name を : で連結) でちょうど 3 行出力してください。

期待される出力:

1: 太郎
2: 花子
3: 次郎

ヒント

  • SELECT id, name FROM users ORDER BY id
  • foreach ($pdo->query($sql) as $row) { ... }
  • 出力は echo $row['id'] . ': ' . $row['name'] . "\n";

🧪 ブラウザで試す

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

PHP ランタイム未読込

          

        

ドリル 02 — 件数を出力

問題

users テーブルの行数を SELECT COUNT(*) で取得し、その数字をちょうど 1 行で出力してください。

users には 3 行入っています (前の drill と同じデータ)。

期待される出力:

3

ヒント

  • SELECT COUNT(*) AS cnt FROM users
  • 1 行 1 列だけ返るので $stmt->fetch(PDO::FETCH_ASSOC) で 1 行だけ取り出す
  • echo $row['cnt'] . "\n";

🧪 ブラウザで試す

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

PHP ランタイム未読込

          

        

ドリル 03 — name 列だけを取り出して改行区切りで出力

問題

users テーブルから name 列だけを id 昇順で取得し、各名前を 1 行ずつ出力してください。

users には 3 行入っています (前の drill と同じデータ)。

期待される出力:

太郎
花子
次郎

ヒント

  • SELECT name FROM users ORDER BY id
  • foreach ($pdo->query($sql) as $row) { echo $row['name'] . "\n"; }
  • fetchAll を使って配列にして foreach でも OK

🧪 ブラウザで試す

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

PHP ランタイム未読込

          

        

演習問題(3問)

  1. ドリル 01 — 全件 SELECT して "id: name" 形式で出力

    README.md starter.php answer.php

  2. ドリル 02 — 件数を出力

    README.md starter.php answer.php

  3. ドリル 03 — name 列だけを取り出して改行区切りで出力

    README.md starter.php answer.php

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

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