PHP ile Cache Yapımı

Cache sistemi özellikle tek bir sayfa da 100 lerce sql komutu girdirip veri çekenler için büyük zaman kazandıran bir özelliktir.

Paylaşacağım cache sınıfı saltun adlı github kullanıcısının ürettiği bir sınıftır ben ise sorun yaşatan durumları çözerek kararlı bir hale getirdim.

Sorunlar kodları minifier ederken açıklama satırı felan varsa tasarımda kaymalara yol açıyordu. Aynı dosyayı yeniden cachelerken farklı isimde kaydediyordu. Buda eğer düzenli cacheleri temizlemiyorsanız veri birikmesine sebep oluyordu.

Scache Sınıfı:

class scache {

	private  $cache = null;
	private  $time = 60;
	private  $status = 0;
	private  $dir = "cache";
	private  $buffer=false;
	private  $start=null;
	private  $load=false;
	private  $gzip_pres=false;
	private  $external=array();
	private  $type=true;
	private  $extension=".html";
	private  $active=true;
	public function __construct($options=NULL,$active=true){
		$this->active=$active;
		if ($active) {
			if (isset($options)) {
				if (is_array($options)) {
					if(isset($options['dir']))    	  $this->dir = $options['dir'];
					if(isset($options['buffer'])) 	  $this->buffer = $options['buffer'];
					if(isset($options['time']))   	  $this->time = $options['time'];
					if(isset($options['load']))  	  $this->load = $options['load'];
					if(isset($options['gzip_pres']))  	  $this->gzip_pres = $options['gzip_pres'];
					if(isset($options['external']))   $this->external = $options['external'];
					if(isset($options['extension']))   $this->extension = $options['extension'];
				}else{
					die('Options only array');
				}
			}
			$myPage=explode('/',$_SERVER["SCRIPT_FILENAME"]);

			foreach ($this->external as $key => $external) {
				if (in_array(end($myPage), $this->external)) {
					$this->type=false;
					break;
				}
			}
			if ($this->type) {
				if(!file_exists($this->dir)){
					mkdir($this->dir, 0777);
				}
				if ($this->load) {
						list($time[1], $time[0]) = explode(' ', microtime());
						$this->start = $time[1] + $time[0];
				}
				 $this->cache  =  $this->dir."/".md5($_SERVER['REQUEST_URI']).$this->extension;
				 if(time() - $this->time < @filemtime($this->cache)) {
				      readfile($this->cache);
				      $this->status=1;
				      die();
				}else {
			      @unlink($this->cache);
				}
			}
		}
	}

	private function writeCache($content){
		$file = fopen($this->cache, 'w');
		$content=$content;
		@fwrite($file, $content);
		fclose($file);
	}

	public function clearCache(){
		$dir = opendir($this->dir);
		while (($file = readdir($dir)) !== false)
		{
			if(! is_dir($file)){
			  unlink($this->dir."/".$file);
			}
		}
		closedir($dir);

	}

    public function gzipKontrol(){
        $kontrol = str_replace(" ","",
            strtolower($_SERVER['HTTP_ACCEPT_ENCODING'])
        );
        $kontrol = explode(",", $kontrol);
        return in_array("gzip", $kontrol);
    }

    public function bosluksil($kaynak){
    	$html = preg_replace(["/\s+/",'/<!-- (.*?) -->/'], " ", $kaynak);
    	return str_replace(['   ','> <'],[' ','><'],$html);
    }

    public function kaynak_presle($kaynak){
        $sayfa_cikti = $this->bosluksil($kaynak);
        if (!$this->gzipKontrol() || headers_sent() || !$this->gzip_pres)
            return $sayfa_cikti;
        header("Content-Encoding: gzip");
        return gzencode($sayfa_cikti);
    }

	public function __destruct(){
		if ($this->active) {
			if ($this->type) {
				if ($this->status==0) {
					if($this->buffer){
						$this->writeCache($this->kaynak_presle(ob_get_contents()));
					}else{
						$this->writeCache(ob_get_contents());
					}

				}
				if ($this->load) {
					list($time[1], $time[0]) = explode(' ', microtime());
					$finish = $time[1] + $time[0];
					$total_time = number_format(($finish - $this->start), 6);
					echo "<!-- Yüklenme Süresi :  {$total_time} -->";
				}
				ob_end_flush();
			}
		}
	}
}

Kullanımı

Genellikle cache sistemini nasıl projesine dahil edeceğini bilmiyor insanlar ben bilmeyenler için kısa bir anlatım yapmak istiyorum.

Tabi kullanım şekli yapınızın içeriğine göre değişiklik gösterir fakat ben genel mantığı anlatacağım bu sınıfı kullanacağınız yer veri tabanı işlemlerinizin başında olmalı eğer sonrasında yapıyorsanız zaten cache kullanmanızın bir manası olmuyor cache amacı zaten aynı sorguları her yeni kullanıcı geldiğinde yaptırmamak 1 kere cache alıp onu yeni gelen kişilere sunmak.

Bu sebeple sınıfı veritabanı işlemlerinizin başına koymalısınız.

Bunu biliyorum ama peki formları post ederken nasıl olacak diye sorarsanız da eğer post ederken varolduğu sayfaya post ediyorsanız get parametresi gönderin böylece onu yeni sayfa olarak görecektir bir post işlemi gerçekleşmiş ise cache oluşturmasını engelleyerek varolduğu sayfa üzerinde post işlemi yapabilirsiniz.

Yada yapınızında bir sabit ajax.php yaparsınız isteği oraya atarsınız kullanım tercihi size kalmış.

$options = [
	'time'   => 86400, // cache süresi
	'dir' =>'/cache', // cache dosyalarının tutulacağı dizin
	'buffer' => false, // true ise html içeriği sıkıştırır
	'load',   => true // true ise yüklenme süresini yazdırır
        'external' => array('nocache.php','nocache2.php'), // Burada belirttiğiniz sayfalar ( dosyalar ) cachelenmez.
	'extension' => ".scache", // standart değer .html olarak ayarlanmıştır cache dosyalarınızın uzantısını temsil etmektedir.
];

$sCache = new scache($options,true); // 2 parametreyi false girerseniz cache almayacaktı

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir