<?php
/**
* Êëàññ äëÿ óïðàâëåíèÿ êåøèðîâàíèåì ñòðàíèöû
*
*/
class Cache {
protected $cache = NULL;
protected $handler = array();
protected $headers = array();
/**
* Ñòàðòóåò êåøèðîâàíèå ñ makeGZip(),
* åñëè ó áðàóçåðà ïðèñóòñòâóåò ñîîòâåöòâóþùèé çàãîëîâîê
*
*/
public function __construct()
{
// âòîðîé ïàðàìåòð ýòî ñòåïåíü áóôôåðèçàöèè 0 > 9
if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip'))
$this->cacheStart('makeGZip', array(5));
else
$this->cacheStart('makeGZip');
}
/**
* Íà÷èíàåò íîâóþ áóôåðèçàöèþ è çàïèñûâàåò åå îáðàáîò÷èê
*
* @param string $func
* @param array $argv
*/
public function cacheStart($func, $argv=NULL)
{
@ob_start();
// notice: íàäî ïåðåäàâàòü èìåííî NULL, à íå FALSE òîãäà ïðè array_merge ýëåìåíò óäàëèòñÿ
$this->handler[] = array($func, $argv);
}
/**
* Î÷èùàåò áóôåð $loop ðàç è âûòàëêèâàåò ïîñëåäíèå $loop îáðàáîò÷èêîâ
*
*/
public function cacheFree($loop=0)
{
$loop = $loop ? $loop : count($this->handler);
for($i=0;$i<=$loop;$i++)
{
@ob_end_clean();
array_pop($this->handler);
}
}
/**
* Ïàðñèò ïîñëåäíèå $loop áóôôåðîâ
*
* @param integer $num
* @return mixed
*/
public function cacheFlush($loop=0)
{
$loop = $loop ? $loop : count($this->handler);
for ($i=$loop-1;$i>=0;$i--)
{
// óçíàåì íîìåð ïîñëåäíåãî õåíäëåðà
$x = count($this->handler)-1;
// ïîëó÷àåì ïîñëåäíèé áóôôåð äëÿ ðàáîòû
$this->cache = @ob_get_contents();
// ñîçäàåì ïðàâèëüíûé ìàññèâ ïàðàìåòðîâ
$params = array_merge((array)$this->cache, (array)$this->handler[$x][1]);
$handler = method_exists($this,$this->handler[$x][0]) ? array($this,$this->handler[$x][0]) : $this->handler[$x][0];
// âûçûâàåì íóæíóþ ôóíêöèþ ñ ïàðàìåòðàìè
$this->cache = call_user_func_array($handler, $params);
// óäàëÿåì ïîñëåäíèé. îòðàáîòàíûé, ýëåìåíò ìàññèâà
array_pop($this->handler);
// îòêëþ÷àåì áóôåðèçàöèþ
@ob_end_clean();
// âûáðàñûâàåì íàçàä ñîäåðæèìîå áóôôåðà
echo $this->cache;
}
return $this->cache;
}
/**
* Ïðèäåðæèâàåò çàãîëîâêè äëÿ îòïðàâêè
*
* @param string $header
*/
public function cacheHeaders($header)
{
// åñëè íàäî ñäåëàòü ïåðåàäðèñàöèþ òî ñìîòðèì ïåðåïèñûâàëèñü ëè url
if(substr($header, 0, 9)=='Location:')
{
foreach($this->handler as $func => $argv)
{
if($func=='makeURL')
{
$rewrite = $this->makeURL("href='".substr($header,10,strlen($header))."'");
header("Location: ".substr($rewrite,6,strlen($rewrite)-7));
exit();
}
}
}
$this->headers[] = $header;
}
/**
* Gzip'èðóåò áóôôåð è âîçâðàùàåò â ïîòîê èëè â ôàéë,
* åñëè èìÿ ôàéëà è ðàñøèðåíèå óêàçàíî
*
* SAMLPE 1
* $cache = &new Cache;
*
* SAMPLE 2
* $cache = &new Cache;
* $cache->cacheFree();
* $cache->cacheStart('makeGZip', array(5,'attachedfile','xml'))
*
* @param mixed $buf
* @param integer $ratio
* @param string $name
* @param string $extention
* @return mixed
*/
public function makeGZip($buf, $ratio=0, $name='', $extention='')
{
if ($ratio === 0) return $buf;
$bufziped = gzcompress($buf, $ratio);
$bufziped = pack('cccccccc',0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00)
.substr($bufziped, 0, -4)
.pack('V',crc32($buf))
.pack('V',strlen($buf));
if (!$name || !$extention)
$this->cacheHeaders('Content-Encoding: gzip');
else
{
$this->cacheHeaders('Content-description: File Transfer');
$this->cacheHeaders('Content-type: application/x-gzip');
$this->cacheHeaders('Content-encoding: gzip/x-gzip');
$this->cacheHeaders('Content-length: '.strlen($bufziped));
$this->cacheHeaders('Content-Disposition: attachment; filename='.$name.'.'.$extention.'.gz');
}
return $bufziped;
}
/**
* Ïàðñèò áóôôåð â ïîèñêàõ ññûëîê è çàìåíÿåò èõ
*
* SAMLPE 1
* href='/somepage.php?action=dosomething&foo=bar&boo=baz#anchor'
* (action|href|src|location|background) - source [href]
* (\"|') - left quote [']
* (\/)? - slash [/]
* ([\/\.a-z0-9]+) - page [somepage]
* (\w+) - extention [php]
* \?? - query string [?]
* (?: (\w+) = (\w+?))? - first parameter = value [action=dosomething] { (\w+) parameter [action] ; (\w+?) value [dosomething] }
* (?: \& (\w+) = (\w+?))? - second parameter = value [foo=bar] { (\w+) parameter [foo] ; (\w+?) value [bar] }
* (?: \& (\S*?))? - other parametrs [boo=baz]
* (\#[-a-zà-ÿ0-9_\ ]*)? - anchor [#anchor]
* (\"|') - right quote
* _makeFolderURL : href='http://localhost/somepage/dosomething/?foo=bar&boo=baz#anchor'
*
* SAMPLE 2
* src="/folder/subfolder/image.jpg"
* (action|href|src|location|background) - source [src]
* (\"|') - left quote ["]
* (\/)? - slash [/]
* ([\/\.a-z0-9]+) - path [folder/subfolder/image]
* (\w+) - extention [jpg]
* (\"|') - right quote ["]
* _makeFolderURL : href="http://localhost/folder/subfolder/image.jpg"
*
* @param mixed $buf
* @return mixed
*/
public function makeURL($buf)
{
// todo : ïåðâûé ïàòåðí = \w+ , ÷åòâåðòûé - ïðîâåðÿòü òùàòåëüíåå
$search = "#(action|href|src|location|background)=(\"|') (\/)? ([\/\.a-z0-9]+) \.(\w+) \?? (?: (\w+) = (\w+?))? (?: \& (\w+) = (\w+?))? (?: \& (\S*?))? (\#[-a-zà-ÿ0-9_\ ]*)?(\"|')#six";
$replace = array($this, "_makeFolderURL");
return preg_replace_callback($search, $replace, $buf);
}
/**
* Ïåðåñîáèðàåò ññûëêè èç ïîëó÷åííîãî ìàññèâà
*
* @return string
*/
private function _makeFolderURL()
{
$args = current(func_get_args()); // count == 12
$string = $args[1]."=".$args[2]."http://".$_SERVER['SERVER_NAME']."/";
$string .= ($args[4]!="index") ? $args[4] : "";
$string .= ($args[5]!="php") ? ".".$args[5] : (($args[4]!="index") ? "/" : "");
$string .= $args[7] ? $args[7]."/" : "" ;
$string .= $args[9] ? "?".$args[8]."=".$args[9] : "";
$string .= $args[10] ? "&".$args[10] : "";
$string .= $args[11] ? $args[11] : "";
$string .= $args[12];
return $string;
}
/**
* Äîáàâëÿåò ñåêðåòíûé êëþ÷ ê ôîðìàì
*
* @param mixed $buf
* @param string $securitykey
* @return mixed
*/
public function makeSecure($buf, $securitykey)
{
$security = "<input type=\"hidden\" name=\"x\" value=\"".$securitykey."\">";
$buf = str_replace("</FORM>", "</form>", $buf);
$buf = str_replace("</form>", $security."</form>", $buf);
return $buf;
}
/**
* Ïîäñâå÷èâàåò òåêñò
*
* SAMPLE 1
* $cache = &new Cache;
* $cache->cacheStart('makeHighlight', array('string to highlight','i','ff0000'));
* echo 'I want to highlight some string';
* $cache->cacheFlush();
* _result : 'I want <i style="background-color:#ff0000">to</i> <i style="background-color:#ff0000">highlight</i> some <i style="background-color:#ff0000">string</i>'
*
* @param mixed $buf
* @param array|string $matches
* @param string $tag
* @param string $color
* @return mixed
*/
public function makeHighlight($buf, $matches, $tag = 'b', $color = 'ffff00')
{
if (!$matches) return $buf;
$matches = (array)$matches;
foreach ($matches as $match) $array[] = preg_quote($match);
return preg_replace('#(?!<.*)(?<!\w)(' . implode('|',$array) . ')(?!\w|[^<>]*>)#i', '<'.$tag.' style="background-color:#'.$color.'">\1</'.$tag.'>', $buf);
}
/**
* XOR'èò òåêñò ïî êëþ÷ó
*
* @param mixed $buf
* @param string $key
* @return mixed
*/
public function makeXOR($buf, $key)
{
$lenk=strlen($key);
$lent=strlen($buf);
for($i=0,$j=0;$i<$lent;$i++,$j++)
{
if($j>=$lenk) $j=0;
$bufxored .= chr(ord($key[$j]) ^ ord($buf[$i]));
}
return $bufxored;
}
/**
* Îòïðàâëÿåò çàãîëîâêè, ïàðñèò è âûâîäèò áóôåð
*
*/
public function __destruct()
{
$this->cacheFlush();
foreach($this->headers as $header) header($header);
}
}
?>