Temporäre Dateien @ PHP

Dynamische Webseiten für mehrfache Verwendung

Statische Webseiten sind gleichbleibende Dateien, die vom Webserver auf Anfrage gesendet werden.
Webseiten für einmaligen Gebrauch werden normalerweise 'dynamisch' mit Server-Programmiersprachen wie Perl, PHP, usw. erstellt.
Den Mittelweg zwischen diesen beiden Varianten bilden Temporäre (Server)-Dateien: Sie werden mit Server-Programmen erzeugt, sind aber für mehrfache Verwendung ausgelegt, z.B. für einige Minuten, Stunden, oder für einen Tag.
PHP Hypertext Processor PHP PHP Hypertext Processor (Datei-I/O)
Methode Automatisch hergestellte Webseiten mit begrenzter Lebenszeit
Analyse Gibt es eine gültige temporäre Datei ?
Neue Datei Erstellung einer neuen temporären Datei
Verwendung Anzeige einer (eingebetteten) temporären Datei
Tipps & Tricks Verzeichnis, Löschen von Dateien, ...
Zufall Zufallsnamen Zufallsnamen für Dateien

Automatisch hergestellte Webseiten mit begrenzter Lebenszeit

Dateien mit begrenzter Lebensdauer eignen sich für wiederverwendbare, jedoch automatisch erstellte Webseiten. Ein Beispiel für die Anwendung ist eine Statistik-Seite, die täglich aktualisiert werden soll.
Statische Webseiten *.html kommen dafür kaum in Betracht, denn sie müssten täglich manuell erstellt und auf den Webserver kopiert werden.
Dynamische Webseiten *.php sind die häufigste Lösung: Sie werden auf Anfrage aktuell erstellt, jedoch nicht gespeichert. Bei hohem Verkehr führt das jedoch zu unnötiger Belastung des Webservers: Die gleiche dynamische Webseite wird dann mehrere hundert- oder tausendmal erzeugt.
Bei Verwendung temporärer Dateien wird die entsprechende Webseite dynamisch am Server erzeugt, jedoch gespeichert. Bei jeder weiteren Anfrage wird die erzeugte temporäre Datei verwendet, und der Server nur minimal belastet.

Arbeitstechnik:

Das Script prüft zuerst, ob die gesuchte Datei in einer aktuellen Version gespeichert ist. Dabei werden veraltete Versionen automatisch gelöscht.
Wenn eine passende Datei gefunden wird (die z.B. vom gleichen Datum stammt), dann wird diese Datei ausgegeben. Das erfolgt rasch und mit minimalem Server-Aufwand.
Wenn keine passende Datei verfügbar ist, wird eine neue Version erstellt und gespeichert. Dieser Aufwand ist geringfügig höher als bei der dynamischen Erzeugung ohne Speichern.
Diese Technik bietet dann besondere Vorteile, wenn
Das Programm komplex ist und/oder relativ viel Rechenzeit erfordert.
Der Verkehr (traffic) hoch ist, die betreffende Webseite oft (z.B. >100mal täglich) angefordert wird.
Nachteile durch Mehr-Aufwand, wenn
Das dynamische Programm (ohne temporäre Datei) kurz ist und rasch ausgeführt wird.
Die Webseite nur selten angefordert wird.

Analyse

Bei Programm-Start wird nach einer passenden Datei (hier minute_*.png) gesucht. Im Dateinamen ist zur Kontrolle die Erstellungszeit enthalten. Sie wird mit der aktuellen Zeit verglichen.
Details: Verzeichnis durchforsten

Das Such-Verzeichnis $verz wird festgelegt und in einer while-Schleife durchsucht.
Mit is_file() werden Dateien ausgefiltert, mit einem Regulären Ausdruck alle Dateien mit passenden Namen (hier minute_*.png).
Die Erstellungszeit $utsf wird ermittelt und mit der aktuellen Zeit verglichen.
Veraltete Dateien (hier>100 Sekunden) werden mit unlink gelöscht.
Details: Datum & Zeit, Reguläre Ausdrücke.

Bei einer zulässigen Datei wird der Pfad $imgsrc gespeichert und die Schleife abgebrochen.
$verz = dir("buffer");
$imgsrc="";
while($fn=$verz->read()&& !strlen($imgsrc))
{
$fnabs = $buffer."/".$fn;
if(is_file($fnabs)) {
if(preg_match("/^minute_.*\.png/",$fn,$regs)) {
$imgsrc = $fn;
// Datei-Alter ?
$utsf = filectime($fnabs);
$dt = time() - $utsf;
if($dt>100) {
$imgsrc = "";
@unlink($fnabs);
}
}
}
}
$verz->close();
Live-Live-PHP-PHP:
Jetzt (hhmmss) = 160723  
Es wurde keine gültige Datei gefunden.

Neue Datei

Wenn keine zutreffende Grafik gefunden wurde, wird eine neue erzeugt.
Details zur programmierten Erzeugung von Grafik mit PHP.

Wichtig für dieses Beispiel ist die Erstellungszeit $st
Sie wird zur Erstellung des Dateinamens $fn verwendet. So kann man die Gültigkeit feststellen, ohne die Datei zu öffnen.
if(!strlen($imgsrc)) {
// Bild erzeugen
$img = imagecreate(200,30);
$f_bg = imagecolorallocate($img,255,208,0);
$f_txt = imagecolorallocate($img,0,0,0);
// Server-Zeit
$st = strftime('H:%M:%S',time());
$s = 'Server-Zeit = '.$st;
imagestring($img,3,14,8,$s,$f_txt);
// Dateiname
$fn = 'minute_'.$st.'.png';
imagepng($img,$fn);
}
Live-Live-PHP-PHP:

Warning: imagecreatefromgif() [function.imagecreatefromgif]: '../../../img/logo/apache_97x32.png' is not a valid GIF file in /home/topsoft.at/www.topsoft.at/pstrainer/entwicklung/php/inout/temporary.php on line 443

Warning: imagecopy() expects parameter 2 to be resource, boolean given in /home/topsoft.at/www.topsoft.at/pstrainer/entwicklung/php/inout/temporary.php on line 444
Grafik-Datei 'minute_160723.png' wurde neu erstellt

Verwendung

Sie erhalten mit dieser Methode immer eine Grafik, die maximal so alt ist wie zulässig, in diesem Fall weniger als 100 Sekunden.
Dieses Beispiel verwendet zur Demonstration eine kurze Lebenszeit und ein kleines Programm. In der Praxis arbeitet die Methode umso besser, je länger die Lebenszeit, und je größer das Programm ist.
→ Dann wird der Server spürbar entlastst.
Datei minute_160723.png wird angezeigt.
Aktuelle Server-Zeit = 16:07:23
Die gezeigte Demo-Grafik ist noch gültig. Diese Seite neu laden
Der PHP-Code zur Einbindung der Grafik ist minimal. Bilder werden in Standard-HTML immer eingebettet, mit anderen Methoden (<iframe>, <object>) können aber auch Texte und ganze Webseiten eingebettet werden.
print "<img src='$imgsrc'>";
Einige Grafiken dieses Webs werden nach dieser Methode erstellt:
Grafik → Zeitgleichung und → Analemma wird täglich nur einmal bei der ersten Anforderung erstellt. Jede weitere Anforderung am gleichen Tag verwendet die gespeicherte Grafik und spart dabei erheblich Server-Zeit.
 

Tipps & Tricks

Verzeichnis:

Zum Speichern benötigt der Webserver Schreib-Rechte im Zielverzeichnis. Das ist bei allen guten Betriebssystemen selbstverständlich, nur bei M$-Systemen ziemlich vernachlässigt.

Zuweisung von Schreib-Rechten kann eine erhebliche Sicherheits-Lücke darstellen ! Speichern sie temporäre Dateien daher nur in einem eigens dafür angelegten Verzeichnis (hier buffer ), das möglichst keine ausführbaren Scripts enthalten sollte.

Dateien löschen:

Jedes Script sollte nur jene Dateien löschen, die es selbst produziert hat.

Jedes Script muss die selbst erstellten Dateien löschen, wenn sie veraltet sind. Ansonsten sammeln sich veraltete Dateien an.

Zufallsnamen für Dateien

In manchen Fällen ist es erforderlich, eine eigene Seite für jede Anfrage zu erstellen. Falls dafür temporäre Dateien erstellt werden, müssen diese eindeutig unterschieden werden. Eine Möglichkeit dafür ist die Vergabe von Zufalls-Namen für die erzeugten Dateien.
PHP-Funktion uniqid() erzeugt Zufalls-Strings von 13 Zeichen Länge. Die Strings auf Basis der Systemzeit sind einander jedoch sehr ähnlich. Daher werden die Strings anschließend mit Funktion md5 verschlüsselt, das ergibt 32 Zeichen lange Strings.
Diese Strings können mit Ziffern beginnen, was für Dateinamen ungünstig ist. Im Beispiel wird daher zusätzlich je ein gleichbleibender String voran- und nachgestellt.
$fnz = uniquid('');
$fnz = md5($fnz);
$fnz = 'test_'.$fnz.'.dat';
Live-Live-PHP-PHP:
$fnz = test_d9e4a56778a201ddb7c62964a18d7480.dat
Alternativ lassen sich beliebig lange Zufallsnamen mit selbst erstellten Funktionen erzeugen: Das Funktionsbeispiel rndstr() erzeugt Zufalls-Strings von beliebiger Länge $len, die mit einem Buchstaben beginnen. Hier werden Kleinbuchstaben verwendet, für Großbuchstaben setzen sie $r+55. Zusätzlich kann je ein String voran- und nachgestellt werden.

Die Wahrscheinlichkeit w, gleiche Zufallsnamen mit n Zeichen (aus 26 Buchstaben und 10 Ziffern) zu erzeugen, ist 1/(36^n), das ergibt bereits für 6 Zeichen w<1E-9

Live-Beispiel (mit Javascript simuliert - klicken sie den Würfel):
$rs = 123456789012345
function rndstr($len,$pre,$post) {
$s = $pre;
for($i=0;$i<$len;$i++) {
if($i) {$r=rand(0,35);}
else {$r=rand(10,35);}
if($r<10) {$s.=chr($r+48);}
else {$s.=chr($r+87);} // Klein
//else {$s.=chr($r+55);} // Groß
}
$s .= $post;
return $s;
}
$rs = rndstr(15,'test_','.dat');
Die PHP-Funktion tempnam() erzeugt sowohl einen Zufalls-Dateinamen als auch eine Datei (!) dieses Namens. Damit wird verhindert, dass auf irgendeinem Wege eine andere Datei gleichen Namens erzeugt wird, bevor das Script die fopen()-Anweisung ausführt.
Als Argumente werden der Verzeichnis-Pfad und der Anfang des Dateinamens (prefix) verwendet.
Sie müssen die Detei wieder (mit unlink() ) löschen - das gilt auch dann, wenn nur tempnam() ausgeführt wurde, und die betreffende Datei niemals verwendet wurde.
$dir = '/buffer';
$fname = tempnam($dir,'test_' );
$fp = fopen($fname,'w');
// ...
fclose($fp);
unlink($fname);

Letzte Änderung dieser Seite: 2011-10-13 14:33:24