Wie ich awesomeBible Verse gebaut habe.

Subscribe to my newsletter and never miss my upcoming articles

Was ist awesomeBible Verse?

awesomeBible Verse ist ein Skript, das dem Besucher jeden Tag ein anderes Versbild zurückgibt.

Wie habe ich das gemacht?

Der größte Teil von awesomeBible Vers ist die Sammlung an Bildern.

Diese lade ich auf GitHub hoch.

Der zweite Teil von awesomeBible Verse ist der Server, das ist einfach eine PHP-Datei. Jetzt möchte ich die einzelnen Teile davon erklären.

<?php
$DayOfYear = date('z') + 1;
$cacheRef = "cacheFile.txt";
$cachedImage = "cachedImage.jpg";

    function cacheStale(){
        global $DayOfYear;
        global $cacheRef;
        global $cachedImage;

        // If cache is stale
            if(file_exists($cachedImage)){unlink($cachedImage);};
            if(file_exists($cacheRef)){unlink($cacheRef);};

            copy('https://raw.githubusercontent.com/awesomebible/verse/master/img/'.$DayOfYear.'.jpg', $cachedImage);

            header('Content-type: image/jpg;');
            header('Cache-Control: max-age 86400');
            echo file_get_contents($cachedImage);

            $myfile = fopen($cacheRef, "w") or die("Unable to open file!");
            $txt = "".$DayOfYear."\n";
            fwrite($myfile, $txt);
            fclose($myfile);
            die;
    };
    function cacheFresh(){
        global $cachedImage;
            // If cache is fresh
            header('Content-type: image/jpg;');
            header('Cache-Control: max-age 86400');
            if(file_exists($cachedImage)){
            echo file_get_contents($cachedImage);
            die;
        }else{
            cacheStale();
        };
    };

    if(file_get_contents($cacheRef) == $DayOfYear){
        cacheFresh();
    }else{
        cacheStale();
    }

    echo "Sorry, but my creator forbid me to do that.";
    echo "<br>";
    echo "Error-Code: ".$DayOfYear."";
?>

Der erste Teil des Codes importiert mit

$DayOfYear = date('z') + 1;
$cacheRef = "cacheFile.txt";
$cachedImage = "cachedImage.jpg";

externe Variablen.

$DayOfYear ruft die date()-Funktion auf, und addiert 1, um den Tag es Jahres herauszubekommen.

1.Januar ist 1, 1.Februar ist 32.

Es wird plus Eins gerechnet, um zu kompensieren, dass in den meisten Programmiersprachen angefangen wird, von 0 loszuzählen. ( Was ist mit dir los Lua? )

$cacheRef speichert den Dateinamen von der Datei, wo der Cache-Status gesichert ist.

$cachedImage speichert den Dateinamen der gecachten Bilddatei.

Als nächstes wird eine If-Abfrage ausgeführt:

if(file_get_contents($cacheRef) == $DayOfYear){
        cacheFresh();
    }else{
        cacheStale();
    }

Diese überprüft mit der file_get_contents()-Funktion, ob der Inhalt der Cache-File der Variable $DayOfYear, also dem aktuellen Datum entspricht.

Ist das der Fall, wird die Funktion cacheFresh() ausgeführt.

Die Funktion cacheFresh() sieht folgendermaßen aus:

    function cacheFresh(){
        global $cachedImage;
            // If cache is fresh
            header('Content-type: image/jpg;');
            header('Cache-Control: max-age 86400');
            if(file_exists($cachedImage)){
            echo file_get_contents($cachedImage);
            die;
        }else{
            cacheStale();
        };
    };

Mit dem Keyword global vor einem Variablennamen, kann man Scoped-Variablen, die eigentlich nicht einer Funktion zur Verfügung stehen würden, weil sie nicht dort definiert wurden, zu globalen Variablen machen. Dann kann man sie auch in solchen Funktionen verwenden, wo es eigentlich nicht möglich wäre.

Hier wird die Variable $cachedImage also der Dateipfad zu dem gecachten Bild zu einer globalen Variable gemacht, um sie auch in dieser Funktion zu verwenden.

Dann wird mit header('Content-type: image/jpg;'); der Content-Type Header auf image/jpg gesetzt.

Der Content-Type Header ist eine Information die bei jeder Anfrage eines Nutzers an eine Website mitgesendet wird, damit der Browser korrekt interpretieren kann, um was für eine Datei es sich handelt.

Der Content-Type Header für das Dokument / auf awesomeBible.de ist zum Beispiel: text/html; charset=UTF-8. content-type.png

Zurück zum Code.

Nach dem Content-Type Header wird ein weiterer Header gesetzt, der dem Browser sagt: Behalte diese Ressource 86400 Sekunden bei dir im Cache, bevor du sie wieder bei mir anfragst.

header('Cache-Control: max-age 86400');

Die 86400 Sekunden sind nicht zufällig gewählt. 86400 Sekunden sind genau ein Tag.

Dann wird überprüft, ob die gecachte Bilddatei noch existiert, und die Datei wird mit echo file_get_contents($cachedImage); an den Nutzer übertragen.

die; schließt zum Abschluss noch die Verbindung.

Wenn das gecachte Bild aus irgendeinem Grund nicht mehr existieren sollte, wird cacheStale() aufgerufen.

function cacheStale(){
        global $DayOfYear;
        global $cacheRef;
        global $cachedImage;

        // If cache is stale
            if(file_exists($cachedImage)){unlink($cachedImage);};
            if(file_exists($cacheRef)){unlink($cacheRef);};

            copy('https://raw.githubusercontent.com/awesomebible/verse/master/img/'.$DayOfYear.'.jpg', $cachedImage);

            header('Content-type: image/jpg;');
            header('Cache-Control: max-age 86400');
            echo file_get_contents($cachedImage);

            $myfile = fopen($cacheRef, "w") or die("Unable to open file!");
            $txt = "".$DayOfYear."\n";
            fwrite($myfile, $txt);
            fclose($myfile);
            die;
    };

Erst werden wieder mit global alle benötigten Variablen importiert. Dann wird mit file_exists() geschaut, ob die Cache-Datei oder die Bilddatei noch existieren. Wenn ja, werden sie mit unlink() gelöscht.

Dann wird mit der copy()-Funktion das Bild von GitHub heruntergeladen.

Dier URL wird aus dem Prefix https://raw.githubusercontent.com/awesomebible/verse/master/img/ der $DayOfYear-Variable und der Dateiendung .jpg zusammengebaut.

Der Bildname ist die $DayOfYear-Variable, weil man ja das Bild für den jeweiligen Tag möchte.

Dann werden wieder wie bereits bekannt der Content-Type und der Cache-Header gesetzt und die Datei wird an den Nutzer übertragen.

Dann wird in die Datei, die in $cacheRef steht der Inhalt der $DayOfYear-Variable herein geschrieben - als Cache-Timestamp.

Dann wird mit fwrite() die Änderung gespeichert, und mit fclose() die Datei geschlossen.

Dann wird die Verbindung mit dem Nutzer - mit die; - abgebrochen und der PHP-Prozess wird terminiert.

Und jetzt?

Jetzt weißt du wie man in PHP globale Variablen benutzt und wofür man sie braucht, du kannst Dateien herunterladen, kopieren, schreiben und speichern.

Du weißt jetzt etwas über HTTP-Header, if-Abfragen und Caching und Prozessterminierung.

Vielleicht wusstest du einiges schon, trotzdem hoffe ich, dass dieser Artikel interessant für dich war. :)

Hier nochmal, falls es dich interessiert:

Comments (1)

Benjamin's photo

Natürlich: Lua ist super flexibel, du kannst bei einem Array bei jeder Zahl anfangen zu zählen, wo du willst. Nur alle Standard-Libraries implementieren es halt ab 1.

lua.png

Ach, ich liebe dich doch Lua! ;)