PHP - ファイル入出力

公開日:2020-12-22 更新日:2020-12-22
[PHP]

1. 概要

ファイルの入出力についてです。

2. ファイル入力(ファイル読み込み)

ファイルを読み込むには、file_get_contents()を使います。

読み込むファイル:c:/test/test.txt
abc
def
ghi
ソース
$s = file_get_contents('C:/test/test.txt');
var_dump($s);
実行結果
string(13) "abc
def
ghi"

上記でファイルは読み込めますが、マルチバイト文字を含んだ UTF-8 以外のシフトJISなどで作成されたファイルは、他の文字に置き換わる文字化けが発生します。
次の内容を、メモ帳で文字コードをANSI(シフトJIS)にして作成して読み込むと文字化けします。
おはようございます
こんにちは
①Ⅳ
実行結果
string(36) "͂悤܂
ɂ
@W"

これは、シフトJISのデータを、UTF-8 として扱っているためです。
文字化けしないようにするには、シフトJISからUTF-8へ変換する必要があります。
変換にはmb_convert_encoding()を使います。
//ファイル読み込み
$s_sjis = file_get_contents('C:/test/test.txt');
var_dump($s_sjis);

// 文字コードの変換:Windows-31J(MS932、CP932) ---> UTF-8 
$s_utf_8 = mb_convert_encoding($s_sjis, "utf-8", "SJIS-win");
//$s_utf_8 = mb_convert_encoding($s_sjis, "utf-8", "SJIS");

var_dump($s_utf_8);
実行結果
string(52) "おはようございます
こんにちは
①Ⅳ"

ちなみに、上記では UTF-8 から SJIS-win に変換していますが、
これは、シフトJISを拡張したもので、「①」や「Ⅳ」などの機種依存文字も含まれます。
そのため、純粋な SJIS に変換すると、「①」や「Ⅳ」が文字化けするので注意してください。

参考
Shift_JIS   --- シフトJIS
SJIS        --- シフトJIS
CP932       --- シフトJIS に、OEMベンダーごとの独自拡張をしたもの。IBMとNECで拡張部分が異なる。
Windows-31J --- CP932の独自拡張を統合したもの。CP932 と言うと、現在はこれを指す。
MS932       --- Javaで定義されている Windows-31J のこと。

3. ファイル出力(ファイル書き込み)

ファイルに書き込むには、file_put_contents() を使います。

$s = <<<EOD
おはよう
こんにちは
こんばんは
EOD;

file_put_contents('C:/test/test2.txt', $s);
実行結果(C:/test/test2.txt)
おはよう
こんにちは
こんばんは
出力されるファイルの文字コードは UTF-8 になります。
シフトJISで出力したい場合は、mb_convert_encoding() で、utf-8 から SJIS-win に変換してから出力してください。

PHPのデフォルトはUTF-8のため、
$s = mb_convert_encoding($s, "SJIS-win", "utf-8");

4. ファイルを読み込み配列に1行ずつ入れる

file() を使うと、ファイルを読み込んで、1行ずつ配列に入れることができます。

読み込むファイル:c:/test/test.txt
abc
def
ghi
ソース
$lines = file('C:/test/test.txt');
foreach ($lines as $line) {
    print($line);
}
実行結果
abc
def
ghi

また、ファイルがシフトJISなどの場合は、mb_convert_encoding() に配列を渡すと、全て変換してくれます。
$lines = mb_convert_encoding($lines, "utf-8", "SJIS");

5. CSVファイルの読み込み

CSVファイルを読み込む際は、fgetcsv() を使うと、1行を列ごとに分割した配列で取得できます。
使う時には、事前に fopen() でファイルを開き、読み込みが終わったら、fclose() でファイルを閉じる必要があります。

引数1 fopen()で取得したファイルポインタ
引数2 1行の最大文字数。入る可能性のある最大文字数。不明な場合は 0 を指定。
引数3 区切り文字
引数4 囲い込み文字
引数5 エスケープ文字
ファイルポインタ以外は省略可能です。

読み込むファイル:c:/test/test.csv(UTF-8)
A,B,C
1,2,3
りんご,みかん,すいか
ソース
if (($handle = fopen('C:/test/test.csv', 'r')) !== FALSE) {
    while (($data = fgetcsv($handle, 4096, ',')) !== FALSE) {
        var_dump($data);
    }
    fclose($handle);
}
実行結果
array(3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
}
array(3) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(1) "3"
}
array(2) {
  [0]=>
  string(19) "りんご,みかん"
  [1]=>
" string(10) "すいか
}

上記の例では「りんご,みかん」が、1つのデータになってしまっています。
fgetcsv() で読み込む場合、文字列の値は、"" で囲うようにしてください。
"" 以外の文字を使う場合は、引数で指定してください。