topic: file-io (read / write / CSV / paths / upload概念) / ch02
ch02 — ファイルを読む
学習目標
file_get_contents()で ファイル全体 を 1 つの文字列として読めるfopen+fgets+fcloseの組み合わせで 1 行ずつ 読める__DIR__ . '/tests/data/foo.txt'のように スクリプトからの相対パス を組める- 読み込んだテキストの 末尾改行 に気をつけて出力できる
所要時間
スライド = 5 分 / ドリル = 約 20 分
ドリル
| # | 内容 |
|---|---|
01-read-all/ |
tests/data/hello.txt の中身をそのまま出力 |
02-read-line-by-line/ |
fgets で 1 行ずつ読み、先頭に 行番号 を付けて出力 |
採点
php scripts/grade.php topics/14-file-io/ch02-read-file/drill/01-read-all/
php scripts/grade.php topics/14-file-io/ch02-read-file/drill/02-read-line-by-line/
確認のコツ
- 読み込み元は drill 内固定パス (
__DIR__ . '/tests/data/...')。リポジトリにコミットされているデータを読み取る形 - このチャプターでは 書き込みは一切しない (ch03 から)
演習問題の詳細
この章の演習問題の内容を読めます。実際に手元で解くには教材リポジトリを clone してください。
ドリル 01 — ファイル全体を読む
問題
__DIR__ . '/tests/data/hello.txt' の中身を そのまま標準出力に出す PHP を書いてください。
データファイル (tests/data/hello.txt):
こんにちは
ファイル読み込みのテスト
期待される出力:
こんにちは
ファイル読み込みのテスト
(末尾の改行はファイルに含まれている前提。echo で追加の "\n" を足さない)
採点
php scripts/grade.php topics/14-file-io/ch02-read-file/drill/01-read-all/
ヒント
$path = __DIR__ . '/tests/data/hello.txt';
echo file_get_contents($path);file_get_contentsは ファイル全体を文字列で返す- 末尾の改行も含めて返すので、
echoだけで OK - パスは
__DIR__基準 で組む (cwd 依存にしない)
つまづいたら
Warning: file_get_contents(...): Failed to open stream→ パスがズレている。__DIR__ . '/tests/data/hello.txt'の綴り //の数を見直す- 末尾に空行が 1 つ余計に出る
→
echo file_get_contents($path) . "\n";のように追加で改行を足していないか確認
ドリル 02 — 1 行ずつ読んで行番号を付ける
問題
__DIR__ . '/tests/data/poem.txt' を 1 行ずつ 読み、各行の先頭に "N: " (N は 1 始まりの行番号) を付けて出力する PHP を書いてください。
データファイル (tests/data/poem.txt):
春はあけぼの
やうやう白くなりゆく山ぎは
すこしあかりて
紫だちたる雲のほそくたなびきたる
期待される出力:
1: 春はあけぼの
2: やうやう白くなりゆく山ぎは
3: すこしあかりて
4: 紫だちたる雲のほそくたなびきたる
採点
php scripts/grade.php topics/14-file-io/ch02-read-file/drill/02-read-line-by-line/
ヒント
$fp = fopen(__DIR__ . '/tests/data/poem.txt', 'r');
$n = 1;
while (($line = fgets($fp)) !== false) {
echo $n . ': ' . rtrim($line, "\r\n") . "\n";
$n++;
}
fclose($fp);fopen($path, 'r')で 読み込みモード で開くfgets($fp)が 1 行返す (EOF でfalse)fgetsの戻り値には 末尾改行 が含まれるのでrtrim($line, "\r\n")で剥がし、自分で"\n"を付け直す- 開いたら必ず
fclose
つまづいたら
- 最後に空行が 1 つ余分に出る
→
fgetsの戻り値末尾の改行を剥がさず、さらに"\n"を付け足している - 1 行ズレる / 行が 1 個多い
→
while (!feof($fp))で書くと末尾で 1 回余分に回ることがある。while (($line = fgets($fp)) !== false)の形で書く
演習問題(2問)
サイト内で問題文・雛形・解答例を確認できます。実際に手元で解くには教材リポジトリを clone してください。