topic: file-io (read / write / CSV / paths / upload概念) / ch01

ch01 — ファイルとは / バイナリ vs テキスト / 文字コード

学習目標

  • 「ファイル = バイト列に名前 (パス) が付いたもの」と絵で言える
  • テキストファイルバイナリファイル の違いを 1 行で説明できる
  • 日本語が混ざるテキストは 文字コード (UTF-8 が標準) を意識する必要があると言える
  • 改行コード (LF / CRLF) で挙動が変わる場面があると知っている

所要時間

スライドのみ = 5 分

ドリル

このチャプターにドリルはありません。 スライドを読み終わったら次の ch02-read-file/ に進んでください。

理由: 「ファイルとは何か」を 絵と言葉で押さえる のが目的。手を動かすのは ch02 から (file_get_contents で実際に読むところ) で行います。

確認してみる (任意)

エディタで適当な .txt ファイルを 1 つ作って、以下を観察すると理解が早い。

echo "こんにちは" > /tmp/hello.txt

# バイト列として見る
wc -c /tmp/hello.txt    # バイト数を出す (UTF-8 で「こんにちは」は 15 バイト + 改行)
xxd /tmp/hello.txt      # 16進ダンプ。1 バイトずつどう並んでいるかが分かる

# テキストとして見る
cat /tmp/hello.txt      # こんにちは

「ファイルの中身 = バイト列」「テキストエディタはそれを文字コード経由で 文字に解釈 している」という関係が腹落ちすれば OK。

解説スライド

教材スライド(Marp)を1枚ずつ表示します。矢印キー(←→)・スワイプ・ナビボタンで移動できます。

  1. <!-- LLM_CONTEXT: Lesson 14 / Chapter 1 目的: ファイルの基本概念 (バイト列 + 名前 / テキスト vs バイナリ / 文字コード / 改行コード) の絵を頭に作る 扱わない: file_get_contents (ch02) / 書き込み (ch03) / CSV (ch04) / パス操作 (ch05) / アップロード (ch06) 読み上げ時間目安: 4 分半〜5 分 -->

    ファイルとは / バイナリ vs テキスト / 文字コード

    Lesson 14 / Chapter 1

  2. ファイルって結局なに?

    hello.txt  ─┐
                ├─ ファイル名 (= ディスク上の場所を指す目印)
                └─ 中身 = ただのバイト列 (0 と 1 が並んだもの)
    • ファイル = バイト列 + 名前 (パス)
    • ディスク (HDD / SSD) 上に保存されていて、電源を切っても消えない
    • 「変数 ($x) はメモリ、ファイルはディスク」と覚える

    → PHP の役目は ディスク上のバイト列を読み出す / 書き込む

  3. テキストファイル vs バイナリファイル

    テキスト バイナリ
    中身 文字 として解釈できるバイト列 文字に直すと意味不明
    .txt / .csv / .json / .html / .php .png / .jpg / .pdf / .zip / .mp4
    エディタで開く 読める 文字化けする (専用ソフトで開く)
    PHP での扱い file_get_contents で文字列として fread でバイト数指定して読む

    L14 で扱うのは テキスト系のみ (.txt / .csv)。画像・PDF などのバイナリは別 lesson。

  4. 「文字コード」 = バイトを文字に翻訳するルール

    バイト: 0xE3 0x81 0x82
                    │
            UTF-8 で解釈
                    ▼
                  「あ」
    • UTF-8 : 今の標準 (Web も PHP も Mac も Linux も基本これ)
    • Shift_JIS : 古い Windows / Excel 由来 (CSV で時々遭遇)
    • EUC-JP : 古い UNIX 系 (ほぼ歴史的存在)

    → 違う文字コードで開くと 文字化け する。「UTF-8 で揃える」 が L14 のお作法。

  5. 改行コード — LF と CRLF

    LF   = "\n"     (= 0x0A)         macOS / Linux の標準
    CRLF = "\r\n"   (= 0x0D 0x0A)    Windows / 一部の Web プロトコル
    場面 どっち
    PHP の \n LF
    php_eol (PHP_EOL 定数) 環境依存
    HTTP ヘッダ CRLF
    Excel が吐く CSV CRLF (Windows) / LF (Mac) どちらもあり得る

    fgetsCRLF も LF もまとめて読む が、末尾に改行が含まれることに注意 (rtrim($line) で外す)。

  6. PHP からファイルを触る基本パターン

    <?php
    // 読む (一発)
    $text = file_get_contents('/path/to/foo.txt');
    
    // 書く (一発)
    file_put_contents('/path/to/foo.txt', "hello\n");
    
    // 1 行ずつ読む (大きなファイル / 行単位処理向き)
    $fp = fopen('/path/to/foo.txt', 'r');
    while (($line = fgets($fp)) !== false) {
        echo $line;
    }
    fclose($fp);
    ▶ 3v4l で実行

    「一発で全部 (file_get_contents / file_put_contents)」と「1 行ずつ (fopen + fgets + fclose)」の 2 系統がある、と頭に入れる。

  7. L14 の作法: 読みは固定 / 書きは一時ディレクトリ

    // 読み込み: drill 内の固定パスから (リポジトリにコミット済み)
    $path = __DIR__ . '/tests/data/hello.txt';
    $text = file_get_contents($path);
    
    // 書き込み: OS の一時ディレクトリへ (採点後に消える)
    $tmp = tempnam(sys_get_temp_dir(), 'dojo_');
    file_put_contents($tmp, "hi\n");
    unlink($tmp);  // 後始末
    ▶ 3v4l で実行
    • __DIR__ = この PHP ファイルがあるディレクトリ。cwd に依存せず安全
    • sys_get_temp_dir() = OS の一時領域 (Mac/Linux なら /tmp)
    • unlink($tmp) で必ず消す。CI で同じ drill を何度回しても汚れない
  8. このチャプターでできるようになること

    ✅ 「ファイル = バイト列 + 名前」と絵で言える ✅ テキスト / バイナリの違いを 1 行で言える ✅ UTF-8 / Shift_JIS の関係 (文字化けの正体) を言える ✅ LF / CRLF の違いと、PHP では \n (LF) が標準だと知っている ✅ 「読みは固定 / 書きは一時ディレクトリ」という L14 の作法を理解した

    → 次の ch02 で、file_get_contents で実際にテキストを読み込む

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

<!-- LLM_CONTEXT: Lesson 14 / Chapter 1 目的: ファイルの基本概念 (バイト列 + 名前 / テキスト vs バイナリ / 文字コード / 改行コード) の絵を頭に作る 扱わない: file_get_contents (ch02) / 書き込み (ch03) / CSV (ch04) / パス操作 (ch05) / アップロード (ch06) 読み上げ時間目安: 4 分半〜5 分 -->

ファイルとは / バイナリ vs テキスト / 文字コード

Lesson 14 / Chapter 1


ファイルって結局なに?

hello.txt  ─┐
            ├─ ファイル名 (= ディスク上の場所を指す目印)
            └─ 中身 = ただのバイト列 (0 と 1 が並んだもの)
  • ファイル = バイト列 + 名前 (パス)
  • ディスク (HDD / SSD) 上に保存されていて、電源を切っても消えない
  • 「変数 ($x) はメモリ、ファイルはディスク」と覚える

→ PHP の役目は ディスク上のバイト列を読み出す / 書き込む


テキストファイル vs バイナリファイル

テキスト バイナリ
中身 文字 として解釈できるバイト列 文字に直すと意味不明
.txt / .csv / .json / .html / .php .png / .jpg / .pdf / .zip / .mp4
エディタで開く 読める 文字化けする (専用ソフトで開く)
PHP での扱い file_get_contents で文字列として fread でバイト数指定して読む

L14 で扱うのは テキスト系のみ (.txt / .csv)。画像・PDF などのバイナリは別 lesson。


「文字コード」 = バイトを文字に翻訳するルール

バイト: 0xE3 0x81 0x82
                │
        UTF-8 で解釈
                ▼
              「あ」
  • UTF-8 : 今の標準 (Web も PHP も Mac も Linux も基本これ)
  • Shift_JIS : 古い Windows / Excel 由来 (CSV で時々遭遇)
  • EUC-JP : 古い UNIX 系 (ほぼ歴史的存在)

→ 違う文字コードで開くと 文字化け する。「UTF-8 で揃える」 が L14 のお作法。


改行コード — LF と CRLF

LF   = "\n"     (= 0x0A)         macOS / Linux の標準
CRLF = "\r\n"   (= 0x0D 0x0A)    Windows / 一部の Web プロトコル
場面 どっち
PHP の \n LF
php_eol (PHP_EOL 定数) 環境依存
HTTP ヘッダ CRLF
Excel が吐く CSV CRLF (Windows) / LF (Mac) どちらもあり得る

fgetsCRLF も LF もまとめて読む が、末尾に改行が含まれることに注意 (rtrim($line) で外す)。


PHP からファイルを触る基本パターン

<?php
// 読む (一発)
$text = file_get_contents('/path/to/foo.txt');

// 書く (一発)
file_put_contents('/path/to/foo.txt', "hello\n");

// 1 行ずつ読む (大きなファイル / 行単位処理向き)
$fp = fopen('/path/to/foo.txt', 'r');
while (($line = fgets($fp)) !== false) {
    echo $line;
}
fclose($fp);
▶ 3v4l で実行

「一発で全部 (file_get_contents / file_put_contents)」と「1 行ずつ (fopen + fgets + fclose)」の 2 系統がある、と頭に入れる。


L14 の作法: 読みは固定 / 書きは一時ディレクトリ

// 読み込み: drill 内の固定パスから (リポジトリにコミット済み)
$path = __DIR__ . '/tests/data/hello.txt';
$text = file_get_contents($path);

// 書き込み: OS の一時ディレクトリへ (採点後に消える)
$tmp = tempnam(sys_get_temp_dir(), 'dojo_');
file_put_contents($tmp, "hi\n");
unlink($tmp);  // 後始末
▶ 3v4l で実行
  • __DIR__ = この PHP ファイルがあるディレクトリ。cwd に依存せず安全
  • sys_get_temp_dir() = OS の一時領域 (Mac/Linux なら /tmp)
  • unlink($tmp) で必ず消す。CI で同じ drill を何度回しても汚れない

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

✅ 「ファイル = バイト列 + 名前」と絵で言える ✅ テキスト / バイナリの違いを 1 行で言える ✅ UTF-8 / Shift_JIS の関係 (文字化けの正体) を言える ✅ LF / CRLF の違いと、PHP では \n (LF) が標準だと知っている ✅ 「読みは固定 / 書きは一時ディレクトリ」という L14 の作法を理解した

→ 次の ch02 で、file_get_contents で実際にテキストを読み込む