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

📝 ドリル 02 — 配列を CSV に書いて読み返す

問題

次の配列を 一時 CSV ファイル に書き出し、その CSV を 読み返して 各行を " | " で結合して 1 行ずつ出力してください。最後に一時ファイルを unlink で消します。

書き出す配列:

$rows = [
    ['id', 'name', 'score'],
    [1, '太郎', 80],
    [2, '花子', 95],
    [3, '次郎', 60],
];
▶ 3v4l で実行

期待される出力 (書き出した CSV を読み返した結果):

id | name | score
1 | 太郎 | 80
2 | 花子 | 95
3 | 次郎 | 60

採点

php scripts/grade.php topics/14-file-io/ch04-csv/drill/02-write-csv/

ヒント

$tmp = tempnam(sys_get_temp_dir(), 'dojo_csv_');

// 書く
$fp = fopen($tmp, 'w');
foreach ($rows as $row) {
    fputcsv($fp, $row, ',', '"', '');
}
fclose($fp);

// 読み返す
$fp = fopen($tmp, 'r');
while (($row = fgetcsv($fp, 0, ',', '"', '')) !== false) {
    echo implode(' | ', $row) . "\n";
}
fclose($fp);

unlink($tmp);
▶ 3v4l で実行
  • fputcsv($fp, $row, ',', '"', '')配列を 1 行の CSV にして書く
  • 読み返しは fgetcsv で 行ごとの配列に戻る → implode(' | ', $row) で表示用に結合
  • 書き込みは sys_get_temp_dir() 配下、最後に unlink で消す

つまづいたら

  • 出力が id | name | score ではなく id|name|score (空白なし) になる → implode(' | ', $row) のセパレータが '|' になっている。前後に空白付きの " | " にする
  • Deprecated 警告が出る → fgetcsv / fputcsv の引数を省略している。第 2〜5 引数を明示 (fgetcsv($fp, 0, ',', '"', '') / fputcsv($fp, $row, ',', '"', ''))
  • 1 行多い・少ない → 「書いた配列」と「読み返した結果」は本来一致する。fputcsv を呼び忘れた / fclose を忘れて flush されていない

テストケース

期待される出力

id | name | score
1 | 太郎 | 80
2 | 花子 | 95
3 | 次郎 | 60

📄 starter.php(雛形)

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

<?php

// 書き出すデータ (PHP の配列)
$rows = [
    ['id', 'name', 'score'],
    [1, '太郎', 80],
    [2, '花子', 95],
    [3, '次郎', 60],
];

// TODO: tempnam(sys_get_temp_dir(), 'dojo_csv_') で一時 CSV パスを作る

// TODO: fopen($tmp, 'w') で開き、foreach で $rows を回しながら
//       fputcsv($fp, $row, ',', '"', '') で 1 行ずつ書き、fclose する

// TODO: fopen($tmp, 'r') で開き直し、
//       while (($row = fgetcsv($fp, 0, ',', '"', '')) !== false) で読み返して
//       echo implode(' | ', $row) . "\n";

// TODO: 最後に fclose して unlink($tmp) で削除する
✅ 解答例を見る(自分で解いてから)
<?php

// 配列を CSV に書く → 読み返して " | " で結合して echo → 削除
$tmp = tempnam(sys_get_temp_dir(), 'dojo_csv_');

$rows = [
    ['id', 'name', 'score'],
    [1, '太郎', 80],
    [2, '花子', 95],
    [3, '次郎', 60],
];

// 書く
$fp = fopen($tmp, 'w');
foreach ($rows as $row) {
    fputcsv($fp, $row, ',', '"', '');
}
fclose($fp);

// 読み返す (= 書いたものの検算)
$fp = fopen($tmp, 'r');
while (($row = fgetcsv($fp, 0, ',', '"', '')) !== false) {
    echo implode(' | ', $row) . "\n";
}
fclose($fp);

unlink($tmp);