PHP: Cache

Når man jobber med PHP er det ikke alltid at man trenger å kjøre tunge SQL spørringer mot databasen for hver sidevisning, da flere operasjoner henter opp den samme informasjonen. Da kan man benytte cache. Jeg opprettet meg en enkel Cache klasse, for å illustrere at det egentlig ikke er en tungvindt prosess, samtidig som man enkelt kan se hvordan cache kan benyttes.

Klassen

class Cache {
    private $Folder = 'cache/';

    public function __construct ($Folder = '') {
        if (isset($Folder) && is_dir ($Folder)) $this->Folder = $Folder;
    }

    private function file ($File) {
        return $this->Folder . sha1 ($File) . '.cached';
    }

    public function get ($File, $TTL = 600) {
        $Filepath = $this->file ($File);
        if (file_exists ($Filepath) && filemtime ($Filepath) > strtotime ('- ' . $TTL . ' seconds'))
            return unserialize (file_get_contents ($Filepath));
        return false;
    }

    public function set ($Filename, $Content) {
        $Filepath = $this->file ($Filename);
        return file_put_contents ($Filepath, serialize($Content)))
    }

    public function flush ($Filename) {
        $Filepath = $this->file ($Filename);
        if (file_exists ($Filepath))
            return unlink ($Filepath);
        return true;
    }
}

Da har man en helt enkel PHP klasse som tar for seg det grunnleggende med Cache. Kort fortalt har man metoder for å hente ut fila, lage ny fil, eller tømme cachen. Problemet til mange er å forstå hvordan man kan benytte en cache. I mitt tilfelle ønsker jeg å lagre cachen som ett array, siden jeg fortsatt skal kunne benytte informasjonen jeg henter opp ifra databasen dynamiskt, selv om at det er ifra cache. I andre tilfeller kan jeg bare lagre hele HTML koden rett i cache, for å spare enda mer datakraft, men da fjerner jeg den dynamiske delen med koden i mitt tilfelle.

En kunde ønsket en FAQ, hvor alle spørsmålene ble listet opp, gruppert etter hvilken kategori de tilhørte, men svarene skulle ikke stå før man valgte å klikke de fram, men siden det var ganske mange kategorier, spørsmål og svar, ønsket dem en cache funksjon på det.

Siden siden skulle være dynamisk for å få fram svarene, tenker man kanskje først at man må cache alle svarene i egne filer, men ved bruk av en array i cachen, trenger man bare én cache fil. Her er hvordan jeg løste det.

$Cache = new Cache;
$CacheName = 'faq';

// Her sjekker jeg opp om det finnes en cache, hvis ikke, så oppretter jeg en cache med ønsket resultat
if (!$Row = $Cache->get ($CacheName)) {
    // Det fantes ingen Cache/den var for gammel, derfor henter jeg ut informasjonen ifra databasen
    // og oppretter en ny cache fil
    $SQL = new SQL (MYSQLHOST, MYSQLUSER, MYSQLPASS, MYSQLDB);
    $Query = 'SELECT s.id AS main_id, s.name, a.id, a.title, a.content
              FROM faq_sections AS s
              INNER JOIN faq_articles AS a ON (s.id = a.section_id)
              ORDER BY a.section_id, a.id';

    $SQL->query ($Query);
    while ($Result = $SQL->fetch_assoc()) {
        $Row[] = $Result;
    }
    $Cache->set ($CacheName, $Row);
    // Debug testing
    echo '<p>LIVE FROM DATABASE</p>';
}

Nå har jeg enten informasjonen ifra cache, eller databasen, i $Row-arrayen, og kan derfor fortsette med vanlig koding under for å vise fram informasjonen jeg ønsker.

I administrasjonspanelet, kan jeg benytte $Cache->flush (‘faq’) når jeg legger inn nye spørsmål og svar, for å gi en oppdatert side til alle brukerne.

Kom gjerne med spørsmål og forslag til klassen.

About Raphael Enevoldsen

Raphael har fagbrev i salgsfaget, og jobber som «tørrvareansvarlig» hos Rema 1000. På fritiden benytter han mye av tiden sin til programmering og har en kreativ hjerne som trenger å mates ofte med endringer.
This entry was posted in blogg and tagged . Bookmark the permalink.

2 Responses to PHP: Cache

  1. Siden du lagrer i en tekstfil, hadde det vært en idé å komprimert innholdet ytterlig med gzencode () / gzcompress() ? Jeg har ikke nyttet meg av disse funksjonene før, så kan ikke si 100 % det vil fungere.

    • byfixar says:

      I teorien vil gzencode/gzcompress gjøre prosessen tregere, da man er avhengig av å pakke ut innholdet for hver gang man skal benytte det. Mulig man kan få det til å bli raskere ved å pakke det ned når det kommer opp i ett par MB, men med tekst/arrayer/ren HTML, vil jeg tro at komprimering bare vil bli ett unødvendig ledd som gjør cachingen tregere. Har ikke testet dette ut i praksis, men min teori tilsier at komprimering vil bli en flaskehals.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Why ask?