Hur cachelagrar man tunga operationer (som databasfrågor) i PHP?
PHP är ett mycket populärt programmeringsspråk för webben. Det är ett bekvämt och kraftfullt, löst skrivet programmeringsspråk som du kan plocka upp och använda inom en kort tidsperiod. Det blir så mycket spritt och populärt kanske tack vare WordPress, ett bloggande eller CMS (Content Management System). Många webbplatser som Facebook är ursprungligen baserade på PHP.
Men PHP anses generellt vara ett långsamt tolkande skriptspråk, även om det finns många tekniker för att accelerera det, t.ex. Zend Optimiser installerad som standard. HHVM hjälper till att kompilera PHP vid körning till något som bytecode, som sedan kan översättas till inbyggd kod, vilket förbättrar prestandan.
Databasfrågor är tidskrävande, särskilt för stora tabeller eller tabeller utan korrekt indexering. Ibland kommer sådana operationer att sakta ner sidladdnings-/bearbetningshastigheten och sedan äventyra användarupplevelsen. Ganska ofta tar sådana frågor tid att slutföra men resultaten kommer inte att ändras så ofta, dvs kanske ändras en gång om dagen. I det här fallet är det bättre att cache dessa resultat i filer och få dem från att läsa filerna nästa gång om de hittas redan cachade.
MySQL-databas är bra på att hantera frågor med korrekt indexering. Men när bordet blir stort påverkar det prestandan. Vi kan cache alla beräkningsintensiva operationer och lagra dem i filer på diskar och hämta dem nästa gång genom att läsa direkt från filerna, vilket kommer att gå mycket snabbare.
Vi har tillhandahållit en PHP-klass som enkelt kan användas för att inkludera i din ansökan.
class Cache {
private $folder = '';
// constructor takes an optional path for storing the cache files
public function __construct($path = '') {
$path = trim($path);
if ((strlen($path) && is_dir($path))) {
$this->setFolder($path);
} else {
$this->setFolder('/tmp/'); // tmp folder if empty
}
}
public function getFolder() {
return $this->folder;
}
public function setFolder($path) {
$path = trim($path);
$len = strlen($path);
if ($len) {
if (is_dir($path)) {
if ($path[$len - 1] != '/') {
$path .= '/'; // adds a forward slashes at the end
}
$this->folder = $path;
}
}
}
// read from caches, if not found, return null
public function read($fileName) {
$fileName = $this->folder.$fileName;
if (is_file($fileName)) {
$handle = fopen($fileName, 'rb'); // open as binary
$variable = fread($handle, filesize($fileName));
fclose($handle);
return unserialize($variable);
} else {
return null;
}
}
// write $variable to $fileName
public function write($fileName, $variable) {
$fileName = $this->folder.$fileName;
$handle = fopen($fileName, 'a');
fwrite($handle, serialize($variable));
fclose($handle);
}
// delete cache entry $fileName
public function delete($fileName) {
$fileName = $this->folder.$fileName;
@unlink($fileName); // put a @ to avoid file-not-found warning
}
}
Så, kommentarerna är på sin plats. Ovanstående klass är enkel och lätt att använda. Till exempel har jag använt följande för att cachelagra en fråga för min webbplats.
require('class.cache.php');
$cache = new Cache('cache/1/');
$entry = md5($url);
$data = $cache->read($entry);
$blogtitle = "";
if ($data !== null) { // found cache
$blogtitle = $data; // read the data
} else {
$query = "select `title` from `blog` where `path`='$url'";
$result = mysql_query($query, $link);
if (mysql_num_rows($result))
{
$blogtitle = mysql_result($result, 0, 0);
}
$cache->write($entry, $blogtitle); // save the cache for next read
}
Så om vi vill rensa cacheminnet kan vi helt enkelt ta bort det genom att:
// suppose we run here the query ("update `blog` set `title` = 'test' where `path` = '$url'");
require('class.cache.php');
$cache = new Cache('cache/1/');
$entry = md5($url);
$cache->delete($entry);
Online CURL header request-verktyget använder denna cacheteknik för att minska CPU-belastningen på webbservern, och dessa cachefiler kommer att rensas med några dagars mellanrum för att förhindra att diskutrymmet på webbservern överbelastas.
Kom ihåg att sidladdningshastigheten är en av faktorerna som påverkar din SEO-poäng. Sökmotorer föredrar snabbare webbplatser.