Wie ich awesomeBible Verse gebaut habe.
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
.
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)