topic: file-io (read / write / CSV / paths / upload概念) / ch04 — CSV を読み書きする / 演習 01

📝 ドリル 01 — CSV を読んで整形出力

問題

__DIR__ . '/tests/data/users.csv' を読み、各データ行を "id: name (age歳)" の形式で出力してください。

データファイル (tests/data/users.csv):

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

期待される出力:

1: 太郎 (20歳)
2: 花子 (25歳)
3: 次郎 (30歳)

(1 行目のヘッダ id,name,age は出力に含めない)

採点

php scripts/grade.php topics/14-file-io/ch04-csv/drill/01-read-csv/

ヒント

$fp = fopen(__DIR__ . '/tests/data/users.csv', 'r');
$header = fgetcsv($fp, 0, ',', '"', '');   // 1 行目を読み捨てる
while (($row = fgetcsv($fp, 0, ',', '"', '')) !== false) {
    [$id, $name, $age] = $row;
    echo "{$id}: {$name} ({$age}歳)\n";
}
fclose($fp);
▶ 3v4l で実行
  • fgetcsv1 行を配列で返す (数値添字)。[0]=id, [1]=name, [2]=age
  • ヘッダ行は ループに入る前に 1 回だけ読み捨てる
  • 配列の分配代入 [$a, $b, $c] = $row; で列を変数に取り出せる (PHP 7.1+)
  • 第 2〜5 引数 (length, separator, enclosure, escape) を明示 — PHP 8.4 以降 で警告が出るのを防ぐ

つまづいたら

  • 出力の 1 行目が "id: name (age歳)" になる → ヘッダ行を 読み捨てていない。ループに入る前に fgetcsv($fp) を 1 回呼ぶ
  • age"20歳" ではなく "20.0歳" になる → (float) キャストや number_format を使っている。fgetcsv の値は 文字列のまま で OK

テストケース

期待される出力

1: 太郎 (20歳)
2: 花子 (25歳)
3: 次郎 (30歳)

📄 starter.php(雛形)

このコードから書き始めてください。

<?php

// TODO: tests/data/users.csv のパスを __DIR__ ベースで組み立てる

// TODO: fopen でファイルを 'r' モードで開く

// TODO: 1 行目 (ヘッダ: id,name,age) を fgetcsv で読み捨てる
//       PHP 8.4+ では 第 2〜5 引数を明示する: fgetcsv($fp, 0, ',', '"', '')

// TODO: while (($row = fgetcsv($fp, 0, ',', '"', '')) !== false) で行ごとに処理
//       [$id, $name, $age] = $row;
//       echo "{$id}: {$name} ({$age}歳)\n";

// TODO: fclose で閉じる
✅ 解答例を見る(自分で解いてから)
<?php

// users.csv (id,name,age) を読み、"id: name (age歳)" の形式で出力する
$path = __DIR__ . '/tests/data/users.csv';
$fp = fopen($path, 'r');
if ($fp === false) {
    fwrite(STDERR, "open failed: $path\n");
    exit(1);
}

// 1 行目 (ヘッダ) を読み捨てる
// PHP 8.4+ では fgetcsv の引数 (length, separator, enclosure, escape) を明示する
$header = fgetcsv($fp, 0, ',', '"', '');

// 2 行目以降をループ
while (($row = fgetcsv($fp, 0, ',', '"', '')) !== false) {
    [$id, $name, $age] = $row;
    echo "{$id}: {$name} ({$age}歳)\n";
}

fclose($fp);