はじめに
他のページのコンテンツを取得したいときにfile_get_contentsやcURLを使うとすごく簡単に実現することができますが、取得しようとするページによってエラーとなってしまうケースがありとても悩みました。
正確にはエラーではないのですが、どんなことが起きていたのかを下にまとめます。
ページによってコンテンツが取得できない
こんなコードを書いていました。
$target_website = "xxxxx";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_website);
$res = curl_exec($ch);
$res_text = htmlspecialchars($res);
echo $res_text;
これを実行すると、成功するページもあれば失敗するページもあり、失敗する場合はエラーが表示されるのではなく、何も表示されません。
同じ処理をfile_get_contentsでも書けて、
$target_website = "xxxxx";
$res = @file_get_contents( $target_website );
$res_text = htmlspecialchars($res);
echo $res_text;
こんな感じにできますが、結果は変わらず。
あれこれ調べたところ、取得しようとするページのencodeに依存していることがわかりました。
つまり、PHPはUTF-8なのに取得しようとするページがSHIFT-JISだったりすると、htmlspecialcharsの処理がうまくいかず、結果が空になってしまうのです。
これを回避するためには、
$target_website = "xxxxx";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_website);
$res = curl_exec($ch);
$res = mb_convert_encoding($res,"UTF-8",'ASCII, JIS, UTF-8, SJIS');//追加
$res_text = htmlspecialchars($res);
echo $res_text;
こんなふうに、mb_convert_encodingを入れてあげれば良いです。
ちなみに
$res = mb_convert_encoding($res,"UTF-8",'auto');
このように「auto」とすればいいのでは?と思うかもしれませんが、これだとうまくいかない場合があります。
下記にも記載がありますが、php.iniの言語設定によっては思った挙動にならないことがあるからです。
終わりに
結構ハマった内容でしたので上記にまとめてみました。
gokeでは100万ユーザーを目指したサービスづくりをしています。