Cacheovaní, kešování
- Sníží zatížení serveru
- Sníží se velikost přenášených dat(gzipace)
- Nepoužívejte na opravdu dynamické stránky, resp. používejte rozumně
//nadefinujme si funkce
function nazev_souboru($newnazev){
$jedna=array("á","ä","ă","â","ć","č","ď","é","ě","ë","í","ĺ","ľ","ň","ó","ř","ŕ","š","ś","ť","ú","ů","ü","ý","ž","ź","Á","Ä","Ă","Â","Ć","Č","Ď","É","Ě","Ë","Í","Ĺ","Ľ","Ň","Ó","Ř","Ŕ","Š","Ś","Ť","Ú","Ů","Ü","Ý","Ž","Ź");
$dva=array("a","a","a","a","c","c","d","e","e","e","i","l","l","n","o","r","r","s","s","t","u","u","u","y","z","z","A","A","A","A","C","C","D","E","E","E","I","L","L","N","O","R","R","S","S","T","U","U","U","Y","Z","Z");
$newnazev = str_replace($jedna, $dva, $newnazev);
$jedna=array("+",">","<",":","°","!","?","=",";","~","/","\\","ˇ","´"," ",",","*","-");
$dva=array("","","","","","","","","","","","","","","_","","","");
$newnazev = str_replace($jedna, $dva, $newnazev);
return $newnazev;
}
function cachestart($regenerate_in_minutes,$_SERVER, $GLOBALS){
$str=$_SERVER['REQUEST_URI'];
$stra=explode("#",$str);
$str=$stra['0'];
$stra=explode("?",$str);
$str=$stra['0'];
$stra=explode("/",$str);
$no="0";
while (!empty($stra[$no]) || $no==0){
$str=$stra[$no];
$no++;
}
$stra="";
$n="0";
while (list($key, $value) = each($GLOBALS)) {
if (!is_array($value)){
$key=nazev_souboru($key);
$value=nazev_souboru($value);
$str=$str."_".$key."-".$value;
$n++;
}}
if ($n<4){
//ok
$accept_enc=$_SERVER['HTTP_ACCEPT_ENCODING'];
if (is_numeric(strpos($accept_enc, "gzip"))){
$gz=TRUE;
}else{$gz=FALSE;}
$f=@fopen("cache/".$str, 'r');
$file=@fstat($f);
@fclose($f);
$mtime=$file['9'];
$s=$regenerate_in_minutes*60;
$s=$mtime+$s;
$t=time();
if ($s>$t){
//ok, je li tam negzipovana verze
$strr=$str;
if ($gz==TRUE){
header ("Content-Encoding: gzip");
header ("Vary: Accept-Encoding");//?cotoje, nedalo by se to odstranit ?
header ("X-Pad: avoid browser bug"); //?cotoje, nedalo by se to odstranit ?
$strr=$strr.".gz";
}
$strr="cache/".$strr; //gz, pokud ho prohlizec prijima
$str="cache/".$str; //ne-gz
if (file_exists($strr)){
readfile($strr);
exit;}else{
if (file_exists($str)){
readfile($str);
exit;}}
}else{return $str;}
}else{
return FALSE;
}
}
function cacheend($filen){
//v end.php. Ulozi vysledek kesovani do souboru
$fp=fopen("cache/".$filen, "w");
$con=ob_get_contents();
$con=zmensi($con);
fwrite($fp,$con);
$file=fstat($fp);
fclose($fp);
$size=$file['7'];
$size2=strlen($con);
if($size==$size2){
}else{
unlink("cache/".$filen);
}
$con=gzencode($con, 9);
$siz=strlen($con);
$fp=fopen("cache/".$filen.".gz", "w");
fwrite($fp,$con);
$file=fstat($fp);
fclose($fp);
$size=$file['7'];
if($size==$siz){
}else{
unlink("cache/".$filen.".gz");
}
}
function clean_cache($string){
$dh = opendir("cache/");
while (($file = readdir($dh)) !== false) {
if ($file!==".." && $file!=="."){
if (!empty($string)){
$sc=strlen($string);
if(substr($file, 0, $sc)==$string){
unlink("cache/".$file);
}
}else{
unlink("cache/".$file); //s prazdnym parametrem smaze celou cachi
}
}
}
closedir($dh);
}
Vypadá to sice, jako, kdybych, když jsem to dělal, byl nalitej, ale není tomu tak...
Návod k použití: Ve složce s kešovanýma věcma je třeba udělat adresář 'cache' a nastavit mu patřičná práva.
Volejte cachestart klidně na začátku všech scriptů, příklad nejsofystikovanějšího použití:
if (empty($_POST) && !array_key_exists("style",$_POST) && !array_key_exists("what",$_GET) && $stranka!=="hlavni"){
$fffile=cachestart("172800",$_SERVER, $_GET);
}
jinak by mělo stačit prosté
$cache_file=cachestart("172800",$_SERVER, $GLOBALS); // to 172800 je v sekundách, tedy se cache udrží 48hodin
a pak na konci scriptu(to už je třeba přesně vydefinovat KDE je to vhodné, například u vkládání příspěvků ani omylem)
if (!empty($cache_file)){
cacheend($cache_file);}
exit;
Docela důležitá je funkce
clean_cache($string). Ta totiž vymaže veškeré
kešované soubory, začínající na $string.
Mimochodem, jména těch souborů se nějak odvozují z parametrů a nechá se to projít funkcí
nazev_souboru(). Například cache stránky forum.php?co=omg bude soubor forum.php_co-omg a
forum.php_co-omg.gz. Ale záleží zcela na tom, co přesně předáváte při volání té funkce
cache_start()...
Jo, zpátky ke clean_cache(): Zavolejte po jakémkoliv změnění obsahu... pokud se obsah mění
moc často, tak se na kešování vyserte a děte se modlit(za server).