Közel 3 hete foglalkoztam a blogon utoljára a kérdéssel, mi legyen a cache-sel. Akkor csak körvonalakban volt meg, hogy mit szeretnék, közben teljesen rendet raktam a káoszban. Első fő kérdés, hogyan tároljam az értékeket. Két lehetőségem volt, serialize
vagy json_encode
. Ezután végeztem egy mérést, hogy melyik a gyorsabb. A tesztnél fontos volt, hogy a letárolás és visszaolvasás együttes sebessége legyen gyorsabb. Így végül a serialize
- unserialize
páros nyerte a versenyt.
Ezután felvetettem a kérdést, hogy letároljam-e a teljes HTML
kimenetet. Ökörség lett volna ezt is szerializálni, úgyhogy ez a lépés kimaradt, helyette kapott a cache egy bővítést, így képes letárolni a teljes HTML
t is. Ezen még majd módosítani kell kicsit, de jelenleg teljesen tökéletesen végzi a dolgát.
Miután kész lett a cache és elfogadható állapotba került, gondoltam egyet, és újraírtam a blog alapját. Eddig egy TextPress motor hajtotta az oldalt, ami a Slim keretrendszerre épült. Ennek egyetlen hátránya volt, hogy nehezen tudtam bővíteni, mert folyamatosan a Slim kódjában kellett matatni. Nehezebb volt hibát keresni benne, nehezebben tudtam új szolgáltatásokat beépíteni. Túl bonyolult volt a rendszer a tudásához képest. A mostani rendszerbe áthoztam pár apróságot a TextPressből, például a bejegyzések formátumát, ami annyit jelent, hogy az md
file elején van egy JSON
fejléc, amiben benne vannak a főbb adatai a bejegyzésnek. Mivel rengeteget olvasgattam mostanában külföldi blogokat, rátaláltam egy másik MarkDown feldolgozóra, amit ParseDown névre kereszteltek. A tesztek szerint jóval gyorsabb, mint a "hivatalos" Markdown parser. Például 1-1 blogbejegyzésem tesztelésekor 6-7× gyorsabban és ráadásul pontosabban jelenítette meg az eredményt.
Tehát a végső cache megoldás megszületett. Jelenleg teljesen file alapú, így a szerverek 95%-án futtatható. Készül egy Memcached változata is, de azt már csak a saját szerveren fogom a kész programban beüzemelni.
A teljes Cache osztály 150 sornyi kódból áll (formázva). Tehát nem túl nagy dolog.
Szóval metódusok:
$path = $this -> get_file_path($keyword);
if (!file_exists($path)) {
return null;
}
$object = unserialize(file_get_contents($path));
if (!empty($object['expired_time']) && time() >= $object['expired_time']) {
@unlink($path);
$this -> auto_cleaner();
return null;
}
if ($get_all) {
return $object;
} else {
return $object['value'];
}
if ((int) $time <= 0) {
$time = 3600 * 24 * 7;
}
$object = array(
"value" => $content,
"write_time" => time(),
"expired_in" => $time,
"expired_time" => time() + (int) $time
);
$value = serialize($object);
$path = $this -> getFilePath($keyword);
$write = 1;
if (file_exists($path) && !$rewrite) {
$old = unserialize(file_get_contents($path));
$write = 0;
if (!empty($old['expired_time']) && time() >= $old['expired_time']) {
$write = 1;
}
}
if ($write) {
file_put_contents($path, $value);
}
$iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(CACHE_FOLDER, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD);
foreach ($iter as $path => $dir) {
if ($dir -> isDir()) {
$path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
foreach (glob($path . '*.Cache') as $file) {
if ($check){
$object = unserialize(file_get_contents($file));
if (!empty($object['expired_time']) && time() >= $object['expired_time']) {
@unlink($file);
}
} else {
@unlink($file);
}
}
}
}
clearstatcache();
$filename = strtolower(trim(preg_replace("/[^a-zA-Z0-9]+/", "_", $keyword), "_"));
$folder = CACHE_FOLDER . substr($filename, 0, 3) . DIRECTORY_SEPARATOR;
if (!file_exists($folder) || !is_dir($folder)) {
mkdir($folder, 0777, 1);
}
return $folder . $filename . '.Cache';
$autoclean = $this -> get('run_auto_cleaner');
if ($autoclean == null) {
$this -> set('run_auto_cleaner', 'auto_clean', 3600);
$this -> clear_expired(1);
}
Ha szeretnél vele játszani kicsit, akkor letölthetővé tettem, magyar kommentekkel: Cache class letöltése