17
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

gzip圧縮が効いたWebページをfile_get_contents()で取得してデコードする方法

Last updated at Posted at 2014-12-03

gzip通信を有効にしてWebページのフェッチを行うと、帯域や通信量が節約できるだけでなく、回線次第では応答速度も速まります。
PHPであればどの環境でも基本的に使えるfile_get_contents関数を用いて、gzip通信を行うサンプルを紹介します。

まず、file_get_contentsと併用してgzipをデコードする実装は大きく分けて2つあります。

  • PHP 5.4 からはgzdecode関数が使える
  • PHP 5.4 未満は次のような実装を自前で用意する必要がある
// その1
if(!function_exists("gzdecode"))
{
    function gzdecode($data){
        return gzinflate(substr($data, 10, -8));
    }
}

// その2
function gzDecodeWithTmpFile($data)
{
    $gzfile = tempnam('/tmp','gzdecode');
    file_put_contents($gzfile, $data);
    ob_start();
    readgzfile($gzfile);
    $result = ob_get_clean();
    return $result;
}

実装サンプル

先ほどの例を踏まえて、PHP5系のバージョン差異を吸収できる実装サンプルは次の通りです。

<?php

class GzipHttpRequest
{
    static public function fetchUrl($url)
    {
        $context = self::getStreamContext();
        $content = file_get_contents($url, false, $context);
        if (self::isGzipResponse($http_response_header)) {
            return self::gzdecode($content);
        } else {
            return $content;
        }
    }

    static private function getStreamContext()
    {
        $opts = array(
            'method' => "GET",
            'header' => implode("\r\n", array('Accept-Encoding: gzip,deflate'))
        );
        return stream_context_create(array('http' => $opts));
    }

    static private function isGzipResponse($headers)
    {
        foreach($headers as $header) {
            if (stristr($header, 'content-encoding') and stristr($header, 'gzip')) {
                return true;
            }
        }
    }

    static private function gzdecode($data)
    {
        if(function_exists("gzdecode")) {
            return gzdecode($data);
        } else {
            return gzinflate(substr($data, 10, -8));
            // 一時ファイルを書き出してデコードする手法もあります
            //return self::gzDecodeWithTmpFile($data);
        }
    }

    static private function gzDecodeWithTmpFile($data)
    {
        $gzfile = tempnam(sys_get_temp_dir(), 'gzdecode');
        file_put_contents($gzfile, $data);
        ob_start();
        readgzfile($gzfile);
        $result = ob_get_clean();
        return $result;
    }
}

$url = "http://www.yahoo.co.jp/";
echo GzipHttpRequest::fetchUrl($url);

curlを使う場合

PHPがcURLサポート付きでコンパイルされており、なおかつcurl 7.10以降を利用している場合には、次のオプションも便利です。

curl_setopt($ch, CURLOPT_ENCODING, 'gzip');

ref. http://php.net/manual/ja/function.curl-setopt.php

参考サイト

17
14
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?