- ベストアンサー
日本語文字化けしないようにファイルを読み込む処理方法
- 日本語が文字化けしないように複数行の日本語文章を特定ファイルから読み込む方法について探しています。
- 現在の処理では文法的に間違っており、文字化けしてしまいます。
- 簡単な処理方法としては、ファイルをUTF-8で開き、各行をmb_convert_encoding関数でUTF-8に変換して表示する方法があります。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
>> $fp = file_get_contents("sample.txt"); ちょっとこれは変数名がよくないですね。ただの文字列に対して「$fp」(FilePointer)は不適切でしょう。PHPの値の型と、fopen・fgets・file_get_contentsのマニュアルを再確認してください。 PHP Manual - 型 http://www.php.net/manual/ja/language.types.php PHP Manual - fopen http://www.php.net/manual/ja/function.fopen.php PHP Manual - fgets http://www.php.net/manual/ja/function.fgets.php PHP Manual - file_get_contents http://www.php.net/manual/ja/function.file-get-contents.php 個人的に「fgets」はほとんど出番がないと思っています。「1行ずつ」読み込んだところでPHPの場合は末端に改行コードが付いてきますし、ちょっと使いにくいと思います。ファイルを処理する関数はいろいろあるので下記を参考にどうぞ。 Qiita - [PHP] ファイルオープンモードに関するマニュアルの記述は間違っている #さまざまなファイル読み出し関数 http://qiita.com/mpyw/items/3adcec3c66e515895b08#2-8 preタグを使わない場合に導入するnl2br関数に関しては、HTMLとする場合は第2引数にfalseを指定すべきです。デフォルトだとXHTML仕様の「<br />」になってしまうので、HTML仕様の「<br>」と違うことに注意してください。 PHP Manual - nl2br http://www.php.net/manual/ja/function.nl2br.php 応用的な方法として、fopen関数で開いたリソースに自動的に文字コードを変換するフィルタをつけることが出来ます。これに関してはマニュアルにも詳しくは載っていません。以下のブログエントリを参考にどうぞ。但し、こちらの方法の場合は文字コードの自動判定は使えないようです。あらかじめ変換元の文字コードを知っていなければなりません。 ぱせらんメモ - ストリームフィルタで文字コード変換してみる http://d.hatena.ne.jp/pasela/20081224/stream_filter CP932(Windowsが名乗っている「Shift_JIS」は実際には「CP932」です)からUTF-8に変換する方法で、あなたが試みようとしたコードに一番近い形で書くならば以下のようになります。「rb」ではなく「r」単体で開くとWindowsであれば改行コードが全て「\r\n」、Linuxであれば「\n」に勝手に変換されるので、ここではOSがWindowsであると仮定します。 if ($fp = fopen('sample.txt', 'r')) { stream_filter_prepend($fp, 'convert.iconv.cp932/utf-8', STREAM_FILTER_READ); flock($fp, LOCK_SH); while (false !== $data = fgets($fp)) { echo rtrim($data) . "<br>\n"; } flock($fp, LOCK_UN); fclose($fp); } ループ条件にfeof関数を含めるのは、ローカルファイルを開く場合は大して問題ないですがネットワークストリームの場合には不適切で汎用的な方法とは言えないので、fgets関数の返り値を調べる方が無難です。PHPのマニュアルもそういう書き方になっていますよね。また、 ehco "$data<br>" とすると、実際にファイルを表示したときにソース上で 1行目[\r\n] <br>2行目[\r\n] <br>3行目[\r\n] <br>4行目 となってしまって非常に不恰好なので、 1行目<br>[\n] 2行目<br>[\n] 3行目<br>[\n] 4行目 となるようにしました。というかこんなことするぐらいなら「1行ずつ」読む意味って全く無いですよね…file_get_contentsを使わないにしても、fopen+stream_get_contentsでいいような気が…
その他の回答 (3)
- agunuz
- ベストアンサー率65% (288/438)
>教えていただいた方法で「fopen」では >できないのでしょうか? fopenが返すのはあくまでもファイルハンドルリソースです。実際にファイルから読込むのは $data = fgets($fp); この部分です。なのでechoしている部分を echo mb_convert_encoding($data, 'utf-8', 'ASCII,JIS,UTF-8,CP51932,SJIS-win') . '<br>'; としてやればいいです。 なお、 ><pre>を使わないと改行はされないのですが nl2br(mb_convert_encoding(file_get_contents('sample.txt'), 'UTF-8', 'ASCII,JIS,UTF-8,CP51932,SJIS-win')) として、改行コードを<br>に変換してやればいいです。
お礼
マニュアルが英語で意味があまり分からず あまり見ていなかったのですが やっと最近少しずつ分かり始めてきました。 ここでいうfopen関数も返り値の型が重要になるのですね。 ありがとうございました!
- yambejp
- ベストアンサー率51% (3827/7415)
>文字化けしないようにデータを読み込んで表示するには ポイントは3つ (1)すでにあるファイルであれば最初からキャラクターセットは わかっているはずなので、それをズバリ指定してやればいい (2)もしなんらかの理由でキャラクターセットのわからないデータを 読まなくてはいけない場合、サンプル数がすくなければどの キャラクターセットなのか判断することは難しい よくエディタでテキストファイルを自動判別開くと文字化けしているようなもの。 そういう場合は、テキストファイル内に特定のキーワードを埋め込むようにして それを見て判断するのが妥当。 (たとえば昔よく利用された美乳やら京やらの文字を入れ込んでおくテクニック UTF8には通用しませんが・・・) 私の利用しているエディタだと「@@」という文字を埋め込んでおくと 自動判定がより正確になります (3)そもそも読み込み時にはきちんと読まれていて、出力時に文字化けしているだけかも。 その場合は、元の文字の文字コード、出力する文字コード、httpヘッダの文字コード htmlであればmetaで指定する文字コードをあわせるとよいでしょう
お礼
これまで文字化けするということはなかったので 文字コードのことは全く気にしていなかったのですが 文字コードの大切さをここで知ることになりました。 まだまだ先は程遠いことを実感しております。 ありがとうございました。
<pre><?=mb_convert_encoding(file_get_contents('sample.txt'), 'UTF-8', 'ASCII,JIS,UTF-8,CP51932,SJIS-win')?></pre> とかでどうですか?mb_convert_encodingの第3引数は省略せずにこのように指定したほうが確実です。これが日本語ファイルを扱う上で最も正確に判定できる順番です。
補足
早速のご回答ありがとうございます。 教えていただいた方法で「file_get_contents」を使うと 上手く文字化けが回避できました。 $fp = file_get_contents("sample.txt"); $fpm = mb_convert_encoding($fp, "UTF-8", "ASCII,JIS,UTF-8,CP51932,SJIS-win"); echo $fpm; <pre>を使わないと改行はされないのですが 課題として後で勉強してみます。 教えていただいた方法で「fopen」では できないのでしょうか? フォームで書き込んだ文字を読み込むのは 「mb_convert_encoding」などを 使わなくても文字化けはしないのですが 読み込んでくるファイルに直接書き込んだりすると 文字化けになってしまうということを 今回はじめて知りました。
お礼
詳しい説明本当に感謝しております。 すぐには理解できるとは思っていませんが 少しずつよんで勉強してみます。 本当にありがとうございました!