スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

file_get_contents()で文字化けさせない方法

【追記あり】
外部サイトのコードを読み取りたい時に、PHPでは

file_get_contents()

という関数が利用できる。
例えばこんな感じ。

$url = "http://yahoo.co.jp";
$html = file_get_contents($url);

お手軽で便利なのだが、参照先のページの文字コードが意に沿わないものだと変換する必要が出てくる。
その時に利用できるのが

mb_convert_encoding($html, $char_to, $char_from)

という関数。
参照したページがJISで、それをUTF-8に変換したい場合、第2引数に「"UTF-8"」、第3引数に「"JIS"」と入れるだけ。
これも非常に簡単。
ただ、複数ページを参照する場合などに$char_from、つまり参照したいページの文字コードを動的に設定したいことがある。実はこの$char_fromには"auto"と設定することができるのだが、経験上autoは絶対使わないことをおすすめする。
判別がうまく出来る場合とできない場合があるためだ。
そこで下記のようにする。
$html = file_get_contents($url);
foreach(array('UTF-8','SJIS','EUC-JP','ASCII','JIS') as $charcode){
if(strcmp(mb_convert_encoding($html, $charcode, $charcode),$html)==0){
$from_encoding = $charcode;
break;
}
}
$html = mb_convert_encoding($html, "utf8", $from_encoding);


想定されるすべての文字コードで変換してみて、変換前後で変化があるかを比較。
もし変換前後で変化がないのであれば(例えばJIS->UTF-8は文字化けするがJIS->JISは変化がない)変換した文字コードがそのページの文字コードである、というブルートフォース的なアプローチだ。
比較には必ずstrcmp()を使うこと。


【追記】
上記の方法だとサイトによっては抜けが出ることがわかった。
そこであれこれ悩んだ結果、ばかみたいな方法だが下記のような手法をとってみた。
とりあえずこちらでは今のところ抜けがない様子。

$html = file_get_contents($url);
$min_pos = 99999999999999;//十分に大きな数字
$from_encoding ='UTF-8';//デフォルト
foreach(array('UTF-8','SJIS','EUC-JP','ASCII','JIS','ISO-2022-JP') as $charcode){
if($min_pos > stripos($html,$charcode,0) && stripos($html,$charcode,0)>0){
$min_pos = stripos($html,$charcode,0);
$from_encoding = $charcode;
}
}
$html = mb_convert_encoding($html, "utf8", $from_encoding);



要するに、ソースコードの中で一番はじめに出てくる文字コード名を採用してしまうという荒業。
1つのページ内で複数の文字コード指定を指定することはまず無いので「ページのトップで文字コードを1回だけ指定する」という前提での方法。
もしページの管理者がページのトップに、

<--! EUC-JPは使わない -->

のようなコメントを残していた場合OUT。

コメント

コメントの投稿

非公開コメント

PR

PR

プロフィール

何でも書くman

Author:何でも書くman
思ったことや備忘録など、とりあえずなんでも書きます。IT系のことや趣味、生活に関わることなども。

ページの先頭へ戻る
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。