PHP - ファイル入出力
公開日:2020-12-22 更新日:2020-12-22
[PHP]
1. 概要
ファイルの入出力についてです。
2. ファイル入力(ファイル読み込み)
ファイルを読み込むには、file_get_contents()を使います。
読み込むファイル:c:/test/test.txt
上記でファイルは読み込めますが、マルチバイト文字を含んだ UTF-8 以外のシフトJISなどで作成されたファイルは、他の文字に置き換わる文字化けが発生します。
次の内容を、メモ帳で文字コードをANSI(シフトJIS)にして作成して読み込むと文字化けします。
これは、シフトJISのデータを、UTF-8 として扱っているためです。
文字化けしないようにするには、シフトJISからUTF-8へ変換する必要があります。
変換にはmb_convert_encoding()を使います。
ちなみに、上記では UTF-8 から SJIS-win に変換していますが、
これは、シフトJISを拡張したもので、「①」や「Ⅳ」などの機種依存文字も含まれます。
そのため、純粋な SJIS に変換すると、「①」や「Ⅳ」が文字化けするので注意してください。
参考
読み込むファイル: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() を使います。
シフトJISで出力したい場合は、mb_convert_encoding() で、utf-8 から SJIS-win に変換してから出力してください。
PHPのデフォルトはUTF-8のため、
$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
また、ファイルがシフトJISなどの場合は、mb_convert_encoding() に配列を渡すと、全て変換してくれます。
読み込むファイル: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)
上記の例では「りんご,みかん」が、1つのデータになってしまっています。
fgetcsv() で読み込む場合、文字列の値は、"" で囲うようにしてください。
"" 以外の文字を使う場合は、引数で指定してください。
使う時には、事前に 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() で読み込む場合、文字列の値は、"" で囲うようにしてください。
"" 以外の文字を使う場合は、引数で指定してください。