概要
書き込みも読み込みと対称で、手軽さの file_put_contents($path, $data) と、制御性の fopen('w') + fwrite + fclose の 2 系統。前者は「文字列を渡すだけで全部書く」、後者は「ハンドルを開きながら何度も書き足す」。普段使いはほぼ file_put_contents で済む。
モードの違い が地味に重要。デフォルトは 上書きモード (既存ファイルの中身を消してから書く)。file_put_contents(..., FILE_APPEND) か fopen($path, 'a') で 追記モード になり、末尾に足す動きに変わる。ログや日次レポートなど「過去分を残しつつ書き足す」用途では追記必須。複数プロセスから同時に書く可能性がある場合は LOCK_EX (排他ロック) を併用する。
教育用ドリルでは 書き込み先を必ず sys_get_temp_dir() 配下 にして、終わったら unlink($tmp) で消す約束。「リポジトリ内のファイルを書き換えない」「CI で何度回しても残骸が残らない」ためのお作法。実務でも tempnam(sys_get_temp_dir(), 'prefix_') で一時ファイルを取って作業し、完了後に消すパターンは頻出。
学習目標
file_put_contents()で 文字列をファイルに書けるfopen('w')+fwrite+fcloseのパターンで書ける- 追記モード (
FILE_APPEND/fopen('a')) と上書きモードの違いを言える - 書き込み先は必ず
sys_get_temp_dir()配下 にして、後でunlinkで消す
ドリル
| # | 内容 |
|---|---|
01-write-and-read/ |
一時ファイルに書いて読み返す (ラウンドトリップ) |
02-append/ |
FILE_APPEND で 2 回書いて、追記されていることを読み返しで確認 |
確認のコツ
- 書き込み先は
tempnam(sys_get_temp_dir(), 'dojo_')で OS の一時領域に作る - 最後に
unlink($tmp)でクリーンアップ (CI が同じ drill を何度回しても汚れない) - リポジトリ内のファイル (
tests/data/...) には 書き込まない
📝 演習: ドリル 01 — 一時ファイルに書いて読み返す
問題
OS の一時ディレクトリに一時ファイルを作って "Hello, File!\n" を書き込み、その中身を読み返して標準出力に出してください。最後にその一時ファイルを unlink で消してください。
期待される出力:
Hello, File!ヒント
$tmp = tempnam(sys_get_temp_dir(), 'dojo_io_');
file_put_contents($tmp, "Hello, File!\n");
echo file_get_contents($tmp);
unlink($tmp);tempnam($dir, $prefix):$dir配下に被らないファイル名を作り、空ファイルを置いてパスを返すsys_get_temp_dir(): OS の一時ディレクトリパス (Mac/Linux なら/tmp)unlink($path): ファイルを削除する
なぜ一時ディレクトリに書くのか
- リポジトリ内 (
__DIR__配下) に書くと、採点を回すたびにリポジトリが汚れる sys_get_temp_dir()配下 +unlinkで消す = 「実行後は何も残らない」 が file-io トピックの作法
つまづいたら
Hello, File!の後に空行が 1 つ余計に出る →echo file_get_contents($tmp) . "\n";のように追加で改行を足していないかunlinkでWarningが出る →tempnamの戻り値 (フルパス) を渡しているか。nullや空文字を渡していないか
📝 演習: ドリル 02 — `FILE_APPEND` で追記する
問題
一時ファイルに以下の順で書き込み、最終的な中身を読み返して出力してください。最後に unlink で削除します。
"line1\n"を書く (上書き)"line2\n"をFILE_APPENDで追記"line3\n"をFILE_APPENDで追記- ファイル全体を読み返して
echo unlinkで消す
期待される出力:
line1
line2
line3ヒント
$tmp = tempnam(sys_get_temp_dir(), 'dojo_io_');
file_put_contents($tmp, "line1\n");
file_put_contents($tmp, "line2\n", FILE_APPEND);
file_put_contents($tmp, "line3\n", FILE_APPEND);
echo file_get_contents($tmp);
unlink($tmp);FILE_APPENDを渡さないと 上書き されて前の中身が消える- ログ書き込みでは
FILE_APPEND | LOCK_EX(排他ロック付き追記) が定番
つまづいたら
- 出力が
line3だけになる → 2 回目以降のfile_put_contentsにFILE_APPENDを渡し忘れている (= 上書き) line1line2line3のように改行が無い → 各文字列の末尾"\n"を書き忘れている ("line1"ではなく"line1\n")