I'm looking for a way to gzip a cached copy of my html and also to server the cached version to users, is this possible? I have this so far...
// at the head
$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();
//at the footer
$cached = fopen($cache_file, 'w');
fwrite($cached, ob_get_contents());
fclose($cached);
ob_end_flush();
Any guidance will be much appreciated.
You don't need to compress each files enable Output Compression in php.ini
and its done automatically
zlib.output_compression = On
Or start output buffer with
ob_start('ob_gzhandler');
Now if the Purpose of your cache is because of speed
and storage space
then don't use filesystem just use Memcached .. it support in built compression
$memcache = new Memcache();
$memcache->addserver("127.0.0.1");
$memcache->add($filename, ob_get_contents(), MEMCACHE_COMPRESSED);
Update
Here is a simple script to manage both file cache and memcache ... you can easly extend it to other types of storage such as mongoDB or redis
Using File System
$storage = new Fcache();
$storage->setDir(__DIR__ . "/cache"); // cache directory
Using Memcache
$storage = new Mcache();
$storage->addserver("127.0.0.1"); // Add Server
Your Script
$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();
}
As you can see $storage
storage can be either file or memcache here is the class used
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);
}
}
Storage
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;
}
}
this class minify and gz html output
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);
}
}?>
sample of use in your php file
<?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());?>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.