1

我正在寻找一种方法来压缩我的 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(); 

任何指导将不胜感激。

4

2 回答 2

2

您不需要压缩每个文件启用输出压缩 php.ini并自动完成

zlib.output_compression = On

或启动输出缓冲区

ob_start('ob_gzhandler');

现在,如果缓存的目的是因为speed然后storage 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

使用内存缓存

$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存储可以是文件或内存缓存,这是使用的类

简单缓存

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;
    }
}
于 2013-05-23T13:13:01.647 回答
1

此类缩小和 gz html 输出

清洁器.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(
        "/ +/" => " ",
        "/<!–\{(.*?)\}–&gt;|<!–(.*?)–&gt;|[\t\r\n]|<!–|–&gt;|\/\/ <!–|\/\/ –&gt;|<!\[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('#<!–[^\[].+–&gt;#', '', $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());?>
于 2013-05-23T13:09:02.583 回答