PHPのcurlでeuc-jpのページを取得したときに文字化けするのを防ぐ


俺日記のしんじです。一人称は僕です。

下記のようなcurlの関数を用意し、euc-jpのページを取得し、シェル内でで取得したページを確認すると文字化けしていることに気づいた。

function curl_get_contents($url, $timeout = 60) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

上記コードを下記のように変更することで文字化けを防ぐことができる。

function curl_get_contents($url, $timeout = 60) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    $result = curl_exec_utf8($ch);
    curl_close($ch);
    return $result;
}

/** The same as curl_exec except tries its best to convert the output to utf8 * */
function curl_exec_utf8($ch) {
    $data = curl_exec($ch);
    if (!is_string($data))
        return $data;

    unset($charset);
    $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);

    /* 1: HTTP Content-Type: header */
    preg_match('@([\w/+]+)(;\s*charset=(\S+))[email protected]', $content_type, $matches);
    if (isset($matches[3]))
        $charset = $matches[3];

    /* 2:  element in the page */
    if (!isset($charset)) {
        preg_match('@ element in the page */
    if (!isset($charset)) {
        preg_match('@<\?xml.+encoding="([^\s"]+)@si', $data, $matches);
        if (isset($matches[1]))
            $charset = $matches[1];
    }

    /* 4: PHP's heuristic detection */
    if (!isset($charset)) {
        $encoding = mb_detect_encoding($data);
        if ($encoding)
            $charset = $encoding;
    }

    /* 5: Default for HTML */
    if (!isset($charset)) {
        if (strstr($content_type, "text/html") === 0)
            $charset = "ISO 8859-1";
    }

    /* Convert it if it is anything but UTF-8 */
    /* You can change "UTF-8"  to "UTF-8//IGNORE" to 
      ignore conversion errors and still output something reasonable */
    if (isset($charset) && strtoupper($charset) != "UTF-8")
        $data = iconv($charset, 'UTF-8', $data);

    return $data;
}

参考:http://stackoverflow.com/questions/2510868/php-convert-curl-exec-output-to-utf8

以上。


投稿者: しんじ

ベトナムでオフショア開発会社経営中 www.bit-vietnam.com 。サービス開発が趣味。web系は主にPHPで、スマホアプリはswiftで。最近はエンジニア向けの英語勉強webアプリ エングリッシュ e-lish.io を作りました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)