
特定ファイルにある複数行の日本語文章を
「fgets」や「file_get_contents」などで画面に読み込む時は、
単純に「mb_convert_encoding」を使えば
良いと思ったのですが
下記のようには文法的にも使えませんでした。
--------------------------------------
<?php
$fp = fopen("sample.txt", "r");
$fp = mb_convert_encoding($fp, "UTF-8"); ←※間違い
if($fp){
flock($fp, LOCK_SH);
while(!feof($fp)){
$data = fgets($fp);
echo "$data<br>";
}
flock($fp, LOCK_UN);
}
fclose($fp);
?>
--------------------------------------
すでに書き込んである
日本語が複数行書かれたファイルから
文字化けしないようにデータを読み込んで表示するには
どのような処理をしたら良いのでしょうか?
複雑な処理はまだ理解できないので
簡単な処理方法があれば
お教えください。
よろしくお願いいたいます。
No.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-c …
個人的に「fgets」はほとんど出番がないと思っています。「1行ずつ」読み込んだところでPHPの場合は末端に改行コードが付いてきますし、ちょっと使いにくいと思います。ファイルを処理する関数はいろいろあるので下記を参考にどうぞ。
Qiita - [PHP] ファイルオープンモードに関するマニュアルの記述は間違っている #さまざまなファイル読み出し関数
http://qiita.com/mpyw/items/3adcec3c66e515895b08 …
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_fil …
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でいいような気が…
詳しい説明本当に感謝しております。
すぐには理解できるとは思っていませんが
少しずつよんで勉強してみます。
本当にありがとうございました!
No.3
- 回答日時:
>教えていただいた方法で「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関数も返り値の型が重要になるのですね。
ありがとうございました!
No.2
- 回答日時:
>文字化けしないようにデータを読み込んで表示するには
ポイントは3つ
(1)すでにあるファイルであれば最初からキャラクターセットは
わかっているはずなので、それをズバリ指定してやればいい
(2)もしなんらかの理由でキャラクターセットのわからないデータを
読まなくてはいけない場合、サンプル数がすくなければどの
キャラクターセットなのか判断することは難しい
よくエディタでテキストファイルを自動判別開くと文字化けしているようなもの。
そういう場合は、テキストファイル内に特定のキーワードを埋め込むようにして
それを見て判断するのが妥当。
(たとえば昔よく利用された美乳やら京やらの文字を入れ込んでおくテクニック
UTF8には通用しませんが・・・)
私の利用しているエディタだと「@@」という文字を埋め込んでおくと
自動判定がより正確になります
(3)そもそも読み込み時にはきちんと読まれていて、出力時に文字化けしているだけかも。
その場合は、元の文字の文字コード、出力する文字コード、httpヘッダの文字コード
htmlであればmetaで指定する文字コードをあわせるとよいでしょう
これまで文字化けするということはなかったので
文字コードのことは全く気にしていなかったのですが
文字コードの大切さをここで知ることになりました。
まだまだ先は程遠いことを実感しております。
ありがとうございました。
No.1
- 回答日時:
<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」などを
使わなくても文字化けはしないのですが
読み込んでくるファイルに直接書き込んだりすると
文字化けになってしまうということを
今回はじめて知りました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
2つの画像ファイルが異なるファ...
-
Zend Framework で大きなファイ...
-
PHPでFilename cannot be empty...
-
phpのftp_get()でエラーが出ます。
-
別のサーバにあるファイルの存...
-
PHPでテキストファイルかどうか...
-
txtファイルに書かれた"東京...
-
PHPでの別のサーバーのテキスト...
-
PHPのファイル操作
-
fopenが動作しない
-
PHPで外部ファイルから取り込ん...
-
PHP CSV データ追加(登録)
-
FTPコマンドでディレクトリごと...
-
ワードプレスではPHPをどこまで...
-
ListViewコントロールでサムネ...
-
Subversionのリポジトリの削除
-
OpenGLで描いて画像ファイル出力
-
別ファイルの変数を呼び出した...
-
HTMLファイルのアップロードに...
-
フォームが送信されたかの確認...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
2つの画像ファイルが異なるファ...
-
PHPでの別のサーバーのテキスト...
-
PHPでFilename cannot be empty...
-
日本語のファイルが開けない
-
ファイルの行数取得
-
phpのftp_get()でエラーが出ます。
-
FirefoxでFormのfileでファイル...
-
ファイル名は、数字の「0」(...
-
stat failed
-
CSVの読み込みと表示
-
日本語が文字化けしないよう読...
-
PHP初心者です、教えていただけ...
-
PHP 読み込んだファイルのブラ...
-
データの受け渡し
-
Zend Framework で大きなファイ...
-
ファイルを白紙にする
-
stdinからの処理でメール情報を...
-
PHP+MySQL でのcsvファイルイン...
-
独自INIファイルの操作をしたい...
-
別のサーバにあるファイルの存...
おすすめ情報