如何使用ob_ gzip缓存文件

时间:2013-05-23 12:49:36

标签: php apache caching

我正在寻找一种方法来gzip我的html的缓存副本以及将缓存版本服务器用户,这可能吗?到目前为止我有这个......

//在头部

$filename   = md5($_SERVER['REQUEST_URI']);
$cache_file = $_SERVER['DOCUMENT_ROOT'].'/pagecache/' . $filename . '.htm';
$cache_time = 86400; // 24 hours

if (file_exists($cache_file) &&
time() - $cache_time < filemtime($cache_file)) {
include($cache_file);
exit;
}
ob_start();

//在页脚

$cached = fopen($cache_file, 'w'); 
fwrite($cached, ob_get_contents());
fclose($cached);
ob_end_flush(); 

非常感谢任何指导。

2 个答案:

答案 0 :(得分:2)

您无需在php.ini中压缩每个文件启用输出压缩,并自动完成

zlib.output_compression = On

或者用

启动输出缓冲区
ob_start('ob_gzhandler');

现在,如果缓存的目的是由于speedstorage space,那么不要使用文件系统只使用Memcached ..它支持内置压缩

$memcache = new Memcache();
$memcache->addserver("127.0.0.1");
$memcache->add($filename, ob_get_contents(), MEMCACHE_COMPRESSED);

<强>更新

这是一个管理文件缓存和内存缓存的简单脚本...您可以轻松地将其扩展到其他类型的存储,例如mongoDB或redis

使用文件系统

$storage = new Fcache();
$storage->setDir(__DIR__ . "/cache"); // cache directory

使用Memcache

$storage = new Mcache();
$storage->addserver("127.0.0.1"); // Add Server

你的剧本

$cache = new SimpleCache($storage);
$cache->setTime(5); // 5 sec for demo

if ($data = $cache->get()) {
    echo "Cached Copy <br />\n";
    echo $data;
} else {
    ob_start();
    while(@$i ++ < 10) {
        echo mt_rand();
    }
    $cache->set(ob_get_contents());
    ob_end_flush();
}

正如您所看到的$storage存储可以是文件或memcache这里是使用的类

SimpleCache

class SimpleCache {
    private $storage;

    function __construct(CacheStorage $storage) {
        $this->storage = $storage;
    }

    public function setTime($time) {
        $this->storage->setTime($time);
    }

    function get() {
        $name = sha1($_SERVER['REQUEST_URI']) . ".cache";
        return $this->storage->read($name);
    }

    function set($content) {
        $name = sha1($_SERVER['REQUEST_URI']) . ".cache";
        $this->storage->write($name, $content);
    }
}

存储

interface CacheStorage {
    public function setTime($time);
    public function read($file);
    public function write($file, $data);
}

// Using Memcache
class Mcache extends Memcache implements CacheStorage {
    private $time = 86400;

    public function setTime($time) {
        $this->time = $time;
    }

    public function read($name) {
        return $this->get($name);
    }

    public function write($name, $data) {
        return $this->add($name, $data, MEMCACHE_COMPRESSED, $this->time);
    }
}

// Using Files System
class Fcache implements CacheStorage {
    private $dir;
    private $time = 86400;

    public function __construct($dir = "cache") {
        $this->setDir($dir);
    }

    public function setDir($dir) {
        $this->dir = $dir;
        if (! is_dir($this->dir) and ! mkdir($this->dir))
            throw new Exception("Invalid Directory");
        $this->dir = $dir;
    }

    public function setTime($time) {
        $this->time = $time;
    }

    public function read($name) {
        $name = $this->dir . "/" . $name;

        if (! is_file($name))
            return false;

        if (time() - filemtime($name) > $this->time)
            return false;

        $zd = gzopen($name, "r");
        $zr = "";
        while(! feof($zd)) {
            $zr .= gzread($zd, 1024);
        }
        gzclose($zd);
        return $zr;
    }

    public function write($name, $data) {
        $name = $this->dir . "/" . $name;
        touch($name);

        $gz = gzopen($name, "w9");
        gzwrite($gz, $data);
        gzclose($gz);
        return true;
    }
}

答案 1 :(得分:1)

这个类缩小和gz html输出

cleaner.php:

<?php  
class Cleaner{
  static function Clean($html){
      $html=preg_replace_callback("~<script(.*?)>(.*?)</script>~si",function($m){
         $m[2]=preg_replace("~//(.*?)\n~si"," ", " ".$m[2]." ");
         return "<script ".$m[1].">".$m[2]."</script>";
      }, $html);
      $search = array(
        "/ +/" => " ",
        "/<!–\{(.*?)\}–>|<!–(.*?)–>|[\t\r\n]|<!–|–>|\/\/ <!–|\/\/ –>|<!\[CDATA\[|\/\/ \]\]>|\]\]>|\/\/\]\]>|\/\/<!\[CDATA\[/" => "");
  //$html = preg_replace(array_keys($search), array_values($search), $html);   
  $search = array(
            "/\/\*(.*?)\*\/|[\t\r\n]/s" => "",
            "/ +\{ +|\{ +| +\{/" => "{",
            "/ +\} +|\} +| +\}/" => "}",
            "/ +: +|: +| +:/" => ":",
            "/ +; +|; +| +;/" => ";",
            "/ +, +|, +| +,/" => ","
       );
       $html = preg_replace(array_keys($search), array_values($search), $html);
       preg_match_all('!(<(?:code|pre|script).*>[^<]+</(?:code|pre|script)>)!',$html,$pre);
       $html = preg_replace('!<(?:code|pre).*>[^<]+</(?:code|pre)>!', '#pre#', $html);
       $html = preg_replace('#<!–[^\[].+–>#', '', $html);
       $html = preg_replace('/[\r\n\t]+/', ' ', $html);
       $html = preg_replace('/>[\s]+</', '><', $html);
       $html = preg_replace('/\s+/', ' ', $html);
       if (!empty($pre[0])) {
         foreach ($pre[0] as $tag) {
             $html = preg_replace('!#pre#!', $tag, $html,1);
         }
      }
      return($html);
  }
  static function Cleaning($html) {

         //put cache  checker here


     $html=self::Clean($html);//if you didn't want to minify commented this line
     if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')){
          $html= "\x1f\x8b\x08\x00\x00\x00\x00\x00".
          substr(gzcompress($html, 9), 0, - 4). // substr -4 isn't needed 
          pack('V', crc32($html)).   // crc32 and 
          pack('V', strlen($html));               // size are ignored by all the browsers i have tested 
          header("Content-Encoding: gzip");
          header('Content-Length: ' . strlen($html));
     }


        //you can save your cache 

      return($html);
 }
}?>

在php文件中使用的样本

 <?php require_once(dirname(__FILE__)."/cleaner.php"); 
 @ob_start(function($m){return Cleaner::Cleaning($m);});?>
 //begin of php file


//end of php file
<?php 
while (@ob_end_flush());?>