PHP Cache Improvements


In [here], a PHP-based framework for caching the website is introduced. The sample PHP psudo-code is given. This post will present some additional improvements based on this framework.

It is configurable that to allow writing caching static htmls only upon human visitors. However, if disabled that (which means the visits from search engines also count), the caching files will be probably ready in a short amount of time, depending on the frequency that spiders/bots grab your site.

Take my site for example, the cached static htmls were built within one day and are still growing (e.g. using du -h cache/ gives the following, from which you can see over 200M static htmls have been built within less than one day).

cache PHP Cache Improvements http I/O File implementation multithreading mysql php SEO software design tools / utilities tricks web programming

The first improvement would be to add file time control. You can easy allow expiry of static files and re-build if necessary by adding the following check.

1
2
3
4
5
6
7
8
9
10
11
12
13
  
function cacheok($cachepage, &$filet) {
  if (file_exists($cachepage)) {
    $today = $_SERVER['REQUEST_TIME'];
    $filet = filemtime($cachepage);  
    $days = round(($today - $filet) / 86400);
    if ($days <= 12)  {
      return (true);
    }
    return (false);
  }
  return (false);
}
  
function cacheok($cachepage, &$filet) {
  if (file_exists($cachepage)) {
    $today = $_SERVER['REQUEST_TIME'];
    $filet = filemtime($cachepage);  
    $days = round(($today - $filet) / 86400);
    if ($days <= 12)  {
      return (true);
    }
    return (false);
  }
  return (false);
}

This function will check if the $cachepage expires or not, you can modify the constant 12, which means 12 days, to suit your needs. The $filet is an out parameter which returns the modification time of the $cachepage.

If you webpage is built based on the query strings, you probably can sort the query parameters, delete unrelated query parameters (that do not affect the HTML output), and finally output a unique idendifier string that is used to store the path of the static cached files.

Have you thought about compressing the cached static HTML files? This can be easily accomplished by adding ob_start(“ob_gzhandler”) right before any HTML content are sent to the browser.

The chances of simultaneous access to the identical pages are great. So it is recommended to use mutexs which prevent the multiple write operation (e.g. file_put_contents) at the same time.

1
2
3
4
5
6
7
include('mutex.php');
$mutex = new Mutex("$cachepage.lock", "cache");
if ($mutex->getLock()) {
  $output = ob_get_contents();
  file_put_contents($cachepage, $output);
}
$mutex->releaseLock();
include('mutex.php');
$mutex = new Mutex("$cachepage.lock", "cache");
if ($mutex->getLock()) {
  $output = ob_get_contents();
  file_put_contents($cachepage, $output);
}
$mutex->releaseLock();

The Mutex class provides an easy process synchronization solution to all PHP threads/processes by using flock (File Lock). Each cache files will be accompany by a ‘.lock’ file which is used to lock the write operation to this static HTML file. TheMutex class is given below, which is very useful in preventing static HTML files crash or incomplete.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
class Mutex {
    private $writeablePath = '';
    private $lockName = '';
    private $fileHandle = null;
 
    public function __construct($lockName, $writeablePath = null) {
        $this->lockName = $lockName;
        if ($writeablePath == null) {
            $this->writeablePath = $this->findWriteablePath($lockName);
        } else {
            $this->writeablePath = $writeablePath;
        }
    }
 
    public function getLock() {
        $h = $this->getFileHandle();
        if (is_bool($h)) {
          return(false);
        }
        return(flock($h, LOCK_EX));
    }
 
    public function getFileHandle() {
        if ($this->fileHandle == null) {
            $this->fileHandle = fopen($this->getLockFilePath(), 'c');
        }
        return($this->fileHandle);
    }
 
    public function releaseLock() {
        $h = $this->getFileHandle();
        if (is_bool($h)) {
          return (false);
        }
        $success = flock($h, LOCK_UN);
        fclose($h);
        return($success);
    }
 
    public function getLockFilePath() {
        return $this->writeablePath . DIRECTORY_SEPARATOR . $this->lockName;
    }
}
?>
<?php
class Mutex {
    private $writeablePath = '';
    private $lockName = '';
    private $fileHandle = null;

    public function __construct($lockName, $writeablePath = null) {
        $this->lockName = $lockName;
        if ($writeablePath == null) {
            $this->writeablePath = $this->findWriteablePath($lockName);
        } else {
            $this->writeablePath = $writeablePath;
        }
    }

    public function getLock() {
        $h = $this->getFileHandle();
        if (is_bool($h)) {
          return(false);
        }
        return(flock($h, LOCK_EX));
    }

    public function getFileHandle() {
        if ($this->fileHandle == null) {
            $this->fileHandle = fopen($this->getLockFilePath(), 'c');
        }
        return($this->fileHandle);
    }

    public function releaseLock() {
        $h = $this->getFileHandle();
        if (is_bool($h)) {
          return (false);
        }
        $success = flock($h, LOCK_UN);
        fclose($h);
        return($success);
    }

    public function getLockFilePath() {
        return $this->writeablePath . DIRECTORY_SEPARATOR . $this->lockName;
    }
}
?>

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
663 words
Last Post: PHP Speed Improvement Tips
Next Post: Some SEO Tips

The Permanent URL is: PHP Cache Improvements

Leave a Reply