Kapitel G Text-Dateien
In diesem Abschnitt wird beschrieben, wie man Textdateien zum Lesen, Schreiben und Speichern von kleineren Datenmengen auf einem Webserver erzeugt.
Kleine Datenmengen
In vielen Fällen muss zur Speicherung von kleineren Datenmengen keine Datenbank angelegt werden. Es reicht aus (z. B. für einen Seitenzugriffszähler), eine einfache Textdatei zu verwenden. In diesem Abschnitt sollen die Funktionen zum Öffnen, Lesen, Schreiben und Schließen von Textdateien behandelt werden.
Sequentielle Dateien
Es handelt sich hier um sogenannte »sequentielle Dateien«. Sie beinhalten Zeilen unterschiedlicher Länge und müssen sowohl beim Schreiben als auch beim Lesen sequentiell (also eine Zeile nach der anderen) bearbeitet werden.
G.1 Lesen einer Zeile aus einer Textdatei  
Datei lesen
Ein einfaches Beispiel, in dem die erste Zeile einer Textdatei gelesen und auf dem Bildschirm ausgegeben wird.
Abbildung G.1 Inhalt der Text-Datei
|
Die Textdatei ug01data.txt wurde zuvor mit einem Texteditor erzeugt und im gleichen Verzeichnis wie die Datei ug01.php abgespeichert. Sie beinhaltet mehrere unterschiedlich lange Zeilen mit Text, wie in Abb. G.1 zu sehen ist:
Mit Hilfe des Programmes wird die erste Zeile der Text-Datei gelesen und wie folgt auf dem Bildschirm ausgegeben:
Abbildung G.2 Lesen aus einer Text-Datei
|
Es folgt der Programmcode:
Listing G.1 Datei ug01.php
<html>
<body>
<?php
$fp = fopen("ug01data.txt","r");
if ($fp)
{
$zeile = fgets($fp, 100);
echo "Inhalt der ersten Zeile der Datei";
echo " ug01data.txt:<p> $zeile";
fclose($fp);
}
else
echo "Datei wurde nicht gefunden";
?>
</body>
</html>
Innerhalb des PHP-Programmes werden die Funktionen fopen(), fgets() und fclose() verwendet.
fopen
Die Funktion fopen() dient zum Öffnen einer Datei.
|
Der erste Parameter gibt den Namen der Datei an. In unserem Beispiel handelt es sich um die Datei mit dem Namen ug01data.txt, die im gleichen Verzeichnis wie das PHP-Programm steht. |
Öffnungsmodus,
»r« = read
|
Der zweite Parameter gibt den Öffnungsmodus an. Hier ist dies "r" (für read), d. h., die Datei wird zum Lesen geöffnet. Andere Öffnungsmodi sind z. B. "w" (für write, Schreiben in eine Datei) und "a" (für append, Anhängen an eine Datei) |
Dateizeiger
|
Rückgabewert der Funktion ist ein sogenannter »Dateizeiger«, er wird in der Variablen $fp gespeichert. Dieser Dateizeiger wird für weitere Zugriffe auf die Datei benötigt. Sollte die Datei am angegebenen Ort nicht existieren, so gibt die Funktion fopen() den Wert false zurück. |
|
Vor der weiteren Benutzung der Datei muss der Rückgabewert geprüft werden. Hier geschieht dies mit if ($fp). |
fgets
Die Funktion fgets() dient zum Lesen einer Zeichenkette aus einer Datei.
|
Der erste Parameter gibt an, aus welcher Datei gelesen werden soll. Dabei muss es sich um den Dateizeiger einer zuvor geöffneten Datei handeln. Hier ist dies $fp. |
Wieviel lesen?
|
Der zweite Parameter gibt die Leselänge an. Es werden entweder (Leselänge – 1) Zeichen aus der Datei gelesen (hier 99) oder bis zum Zeilenumbruch oder bis zum Ende der Datei. Dies gilt je nachdem, was zuerst eintritt. Man sollte zum Lesen ganzer Zeilen eine Leselänge wählen, die auf jeden Fall für die betreffende Datei ausreicht. |
|
Rückgabewert der Funktion ist die gelesene Zeichenkette (einschließlich des Zeilenumbruches). Sie wird hier in der Variablen $zeile gespeichert. Diese Variable wird auf dem Bildschirm ausgegeben. |
fclose
Die Funktion fclose() dient zum Schließen einer Datei.
|
Der Parameter gibt an, welche Datei geschlossen werden soll. Dabei muss es sich um den Dateizeiger einer zuvor geöffneten Datei handeln. Hier ist dies $fp. |
|
Man sollte geöffnete Dateien immer schließen, auch wenn nach Beendigung eines PHP-Programmes alle beteiligten Dateien geschlossen werden. Ansonsten könnte das Betriebssystem weitere Zugriffe auf diese Datei verwehren, da es diese Datei noch für geöffnet hält. |
G.2 Lesen aller Zeilen einer Textdatei  
Im nachfolgenden Beispiel, werden alle Zeilen einer Textdatei gelesen und auf dem Bildschirm ausgegeben:
Listing G.2 Datei ug02.php
<html>
<body>
<?php
$fp = fopen("ug01data.txt","r");
if ($fp)
{
while (!feof($fp))
{
$zeile = fgets($fp, 100);
echo "Zeile: $zeile<p>";
}
fclose($fp);
}
else
echo "Datei wurde nicht gefunden";
?>
</body>
</html>
feof
Die Funktion feof() dient dazu, das Ende einer Datei zu signalisieren.
|
Der Parameter gibt den an, welche Datei geprüft werden soll. Dabei muss es sich um den Dateizeiger einer zuvor geöffneten Datei handeln. Hier ist dies $fp. |
|
Rückgabewert der Funktion ist true, falls das Ende der Datei festgestellt wurde, bzw. false wenn dies nicht der Fall ist. |
Lesen bis zum Ende
Im Programm wurde eine bedingungsgesteuerte Schleife verwendet. Diese wird wiederholt, solange das Ende der Datei noch nicht erreicht wurde (while (!feof($fp)). Nach dem Lesen einer Zeile durch die Funktion fgets wird der Dateizeiger $fp automatisch auf den Anfang der nächsten Zeile gesetzt.
Im vorliegenden Fall wurde vorausgesetzt, dass die Datei ug01data.txt mit einem Text-Editor in folgender Weise erzeugt wurde:
|
Schreiben der ersten Zeile (¢) |
|
Schreiben der zweiten Zeile (¢) |
|
..... |
|
Schreiben der vorletzten Zeile (¢) |
|
Schreiben der letzten Zeile (Abspeichern und Schließen der Datei) ohne (¢) |
Falls man nach der letzten Zeile noch einen oder mehrere Zeilenumbrüche erzeugt hat und die Datei anschließend erst gespeichert und geschlossen hat, werden beim Lesen diese unnötigen leeren Zeilen ebenfalls erfasst und können zu Fehlausgaben führen (z. B. falsche Zeilenanzahl).
Übung UG03
Schreiben Sie mit Hilfe eines Texteditors mehrere Namen in eine Textdatei (Datei ug03data.txt). Jeder Name soll zweizeilig geschrieben werden, in der ersten Zeile der Vorname, in der zweiten Zeile der Nachname. Erzeugen Sie ein PHP-Programm (Datei ug03.php), das diese Datei öffnet, liest und die Namen in einer HTML-Tabelle in der folgenden Form (zusätzlich mit laufender Nummer) auf dem Bildschirm ausgibt:
Nummer |
Nachname |
Vorname |
1 |
Mertens |
Peter |
2 |
Huber |
Josef |
3 |
Weber |
Julia |
G.3 Überschreiben einer Textdatei  
Datei schreiben
Beim Schreiben in Dateien gilt es zu bedenken, dass die betreffende Datei auf dem Webserver liegt und von mehreren Benutzern gleichzeitig bearbeitet werden kann.
Datei sperren
Damit es dabei nicht zu Konflikten kommt, muss die Datei nach dem Öffnen zeitweilig gesperrt werden, so dass ein einzelner Benutzer sie beschreiben kann. Anschließend muss die Sperre wieder aufgehoben werden.
Im nachfolgenden Beispiel werden einige Zahlen und Zeichenketten in eine Textdatei geschrieben:
Listing G.3 Datei ug04.php
<html>
<body>
<?php
$fp = fopen("ug04data.txt","w");
if ($fp)
{
flock($fp,2);
$nl = chr(13) . chr(10);
fputs ($fp, "Autor: Max Maier$nl");
for ($i=10; $i<=50; $i=$i+10)
{
fputs ($fp, "$i$nl");
}
fputs ($fp, "Autor: Max Maier$nl", 6);
echo "Ausgabe in Datei geschrieben";
flock($fp,3);
fclose($fp);
}
else
{
echo "Datei konnte nicht zum";
echo " Schreiben geöffnet werden";
}
?>
</body>
</html>
»w« = write
Die Datei ug04data.txt wird mit der Funktion fopen(), Öffnungsmodus "w" (für write), zum Schreiben geöffnet. Falls die Datei bereits existiert, wird sie dabei überschrieben! Weitere Vorgänge sollten auch hier erst erfolgen, nachdem kontrolliert wurde, ob das Öffnen erfolgreich war.
flock
Die Funktion flock() dient zum Sperren einer Datei.
|
Der erste Parameter gibt an, welche Datei gesperrt werden soll. Dabei muss es sich um den Dateizeiger einer zuvor geöffneten Datei handeln. Hier ist dies $fp. |
|
Der zweite Parameter gibt die Art der gewünschten Operation an. Mit Hilfe des Wertes 2 kann man die Datei exklusiv sperren, so dass sie nur noch vom aktuellen Programm bearbeitet werden kann. Mit Hilfe des Wertes 3 kann man eine Sperre wieder aufheben, woraufhin die Datei wieder von anderen Programmen bearbeitet werden kann. |
Neue Zeile
In der Variablen $nl wird mit Hilfe der Zeichenkettenfunktion chr() ein Zeilenvorschub abgespeichert. Ein Zeilenvorschub besteht aus den beiden ASCII-Zeichen mit dem Code 13 (entspricht CR = Carriage Return = Wagenrücklauf) und 10 (entspricht LF = Line Feed = Zeilensprung). Weitere Informationen zu Zeichenkettenfunktionen finden sich im betreffenden Abschnitt. Der Zeilenvorschub wird ebenfalls ausgegeben.
fputs
Die Funktion fputs() dient zur Ausgabe von Zeichenketten in eine Datei.
|
Der erste Parameter gibt an, in welche Datei ausgegeben werden soll. Dabei muss es sich um den Dateizeiger einer zuvor geöffneten Datei handeln. Hier ist dies $fp. |
|
Der zweite Parameter beinhaltet die auszugebende Zeichenkette |
|
Der dritte Parameter ist optional, er begrenzt die Länge der Ausgabe auf die angegebene Anzahl. Hier wurde der dritte Parameter nur zu Demonstrationszwecken bei der letzten Ausgabe verwendet. Diese Ausgabe wird nach dem sechsten Zeichen abgeschnitten. |
Die Ausgabedatei hat folgenden Inhalt:
Autor: Max Maier
10
20
30
40
50
Autor:
G.4 Anhängen an eine Textdatei  
An Datei anhängen
Im nachfolgenden Beispiel werden die Inhalte einiger Formularfelder fortlaufend in eine Textdatei geschrieben. Zunächst die Datei mit dem Eingabe-Formular:
Listing G.4 Datei ug05.htm
<html>
<body>
Bitte geben Sie Ihre Adresse ein:
<form action = "ug05.php" method = "post">
<input size="20" name="nn"> Nachname<p>
<input size="20" name="vn"> Vorname<p>
<input size="20" name="sr">
<input size="10" name="hn"> Straße und Hausnummer<p>
<input size="10" name="pz">
<input size="20" name="st"> PLZ und Stadt<p>
<input type="submit" value="Senden">
<input type="reset">
</form>
</body>
</html>
Nach dem Absenden werden diese Daten von dem nachfolgenden PHP-Programm weiterverarbeitet:
Listing G.5 Datei ug05.php
<html>
<body>
<?php
$fp = fopen("ug05data.txt","a");
if ($fp)
{
flock($fp,2);
$nl = chr(13) . chr(10);
fputs ($fp, "$nn;$vn;$sr;$hn;$pz;$st$nl");
echo "Vielen Dank, $vn $nn<p>";
echo "Ihre Angaben wurden gespeichert<p>";
flock($fp,3);
fclose($fp);
}
else
{
echo "Datei konnte nicht zum";
echo " Schreiben geöffnet werden";
}
?>
Zurück zur <a href="ug05.htm">Eingabe</a>
</body>
</html>
»a« = append
Die Datei ug05data.txt wird mit der Funktion fopen(), Öffnungsmodus "a" (für append), zum Schreiben am Ende der Datei geöffnet. Weitere Vorgänge sollten auch hier erst erfolgen, nachdem kontrolliert wurde, ob das Öffnen erfolgreich war.
Die Daten aus dem Formular werden, jeweils durch ein Semikolon voneinander getrennt, in die Ausgabedatei geschrieben. Am Ende der Zeile wird ein Zeilenvorschub erzeugt.
Mit Hilfe eines Hyperlinks kann der Benutzer zum Eingabe-Formular zurückgelangen und weitere Eingaben vornehmen. Jede weitere Eingabe wird an die vorhandene Datei angehängt.
Übung UG06
In einer Textdatei (ug06data.txt) stehen mehrere Datensätze in der folgenden Form:
|
Erste Zeile: Laufende Nummer |
|
Zweite Zeile: Nachname |
|
Dritte Zeile: Vorname |
Schreiben Sie ein PHP-Programm (Datei ug06.php), das diese Datei öffnet, liest und die Datensätze in der gleichen Form in zwei verschiedene Dateien ausgibt:
|
Datensätze mit einer laufenden Nummer unter 1000 in Datei ug06a.txt. Diese Datei soll bei jeder Benutzung überschrieben werden. |
|
Alle anderen Datensätze in Datei ug06b.txt. An diese Datei sollen die Datensätze jeweils angehängt werden. |
Auf dem Bildschirm soll zur Kontrolle ausgegeben werden:
Es wurden xxx Datensätze gefunden
davon wurden xxx Datensätze in die Datei ug06a.txt geschrieben
und xxx Datensätze an die Datei ug06b.txt angehängt.
Anmerkung: Die Funktion fgets() liest die Zeilen einschließlich des Zeilenumbruches in eine Variable. Wird diese Variable in eine Datei ausgegeben, so wird auch der Zeilenumbruch ausgeführt, er braucht nicht zusätzlich ausgegeben zu werden.
G.5 Ein einfacher Zugriffszähler  
Zugriffszähler
Im nachfolgenden Beispiel wird ein Zähler realisiert, der die Anzahl der Zugriffe auf eine Datei festhält. Ein solcher wird im Internet oft eingesetzt, um die Beliebtheit bzw. den Erfolg einer Web-Seite zu messen.
Listing G.6 Datei ug07.php
<html>
<body>
<?
$fn = "ug07data.txt";
if (file_exists($fn))
{
/* alte Zahl lesen */
$fp = fopen($fn,"r");
$zahl = fgets($fp,10);
fclose($fp);
}
else
/* erster Zugriff */
$zahl = 0;
/* Zahl erhöhen */
$zahl = $zahl + 1;
echo "Der Zugriffszähler steht auf $zahl";
/* neue Zahl schreiben */
$fp = fopen($fn,"w");
flock($fp,2);
fputs($fp,$zahl);
flock($fp,3);
fclose($fp);
?>
</body>
</html>
Zunächst wird der Dateiname in der Variablen $fn gespeichert, da er mehrmals innerhalb des Programmes benötigt wird.
Die Funktion file_exists() dient der Kontrolle, ob die Zähler-Datei mit dem ug07data.txt im gleichen Verzeichnis existiert. Falls es sich um den ersten Zugriff auf die Datei handelt, so existiert die Datei noch nicht und der Zähler wird auf 0 gesetzt. Anderenfalls wird der aktuelle Zählerstand aus der Datei in die Variable $zahl gelesen.
Diese Variable wird um 1 erhöht, ausgegeben und anschließend in die Datei geschrieben, so dass sie für den nächsten Zugriff den richtigen Wert bereitstellt.
G.6 Alle Funktionen für Dateien und Verzeichnisse  
Alle Funktionen
Im vorliegenden Abschnitt werden eine ganze Reihe von PHP-Funktionen für die Behandlung von Dateien und Verzeichnissen eingesetzt. Zur besseren Übersicht zeigen wir zunächst eine Liste mit allen Funktionen und einer kurzen Erläuterung. Weitergehende Ausführungen finden sich im PHP Manual.
Funktionsname |
Erläuterung |
basename() |
Gibt den Namen einer Datei aus einer vollständigen Pfadangabe zurück |
chgrp() |
Wechselt die Gruppenzugehörigkeit einer Datei |
chmod() |
Ändert die Zugriffsrechte einer Datei |
chown() |
Ändert den Eigentümer einer Datei |
clearstatcache() |
Löscht den Status Cache |
copy() |
Kopiert eine Datei |
delete() |
Dies ist ein leerer Eintrag, falls nach einer Funktion zum Löschen einer Datei gesucht wird (s. unlink()) |
dirname() |
Extrahiert den Verzeichnis-Namen aus einer vollständigen Pfadangabe |
diskfreespace() |
Gibt den freien Speicherplatz in einem Verzeichnis zurück |
fclose() |
Schließt einen offenen Dateizeiger |
feof() |
Prüft, ob der Dateizeiger am Ende der Datei steht |
fgetc() |
Liest das Zeichen, auf welches der Dateizeiger zeigt |
fgetcsv() |
Liest eine Zeile von der Position des Dateizeigers aus und überprüft diese auf Komma-separierte Werte (CSV) |
fgets() |
Liest eine Zeile von der Position des Dateizeigers aus |
fgetss() |
Liest eine Zeile von der aktuellen Position des Dateizeigers aus und entfernt HTML und PHP-Tags |
file() |
Liest eine Datei komplett in ein Array |
file_exists() |
Überprüft, ob eine Datei existiert |
fileatime() |
Gibt Datum und Uhrzeit des letzten Zugriffs auf eine Datei zurück |
filectime() |
Gibt Datum und Uhrzeit der letzten Änderung des Dateizeigers Inode zurück |
filegroup() |
Gibt die Gruppenzugehörigkeit einer Datei zurück |
fileinode() |
Gibt Inode-Nummer einer Datei aus |
filemtime() |
Gibt Datum und Uhrzeit der letzten Dateiänderung aus |
fileowner() |
Gibt den Dateieigentümer aus |
fileperms() |
Gibt die Zugriffsrechte einer Datei aus |
filesize() |
Gibt die Größe einer Datei aus |
filetype() |
Gibt den Typ einer Datei zurück |
flock() |
Sperren einer Datei |
fopen() |
Öffnet eine Datei oder URL |
fpassthru() |
Gibt alle restlichen Daten eines Dateizeigers direkt aus |
fputs() |
Schreibt Daten an die Position des Dateizeigers |
fread() |
Liest Binär-Dateien aus einer Datei |
fseek() |
Positioniert den Dateizeiger um einen Offset ’offset’ vor oder zurück |
ftell() |
Ermittelt die aktuelle Position des Dateizeigers |
fwrite() |
Schreibt Binärdaten in eine Datei |
is_dir() |
Ermittelt, ob der gegebene Dateiname ein Verzeichnis ist |
is_executable() |
Ermittelt, ob eine Datei ausführbar ist |
is_file() |
Ermittelt, ob der Dateiname eine reguläre Datei ist |
is_link() |
Ermittelt, ob der Dateiname ein symbolischer Link ist |
is_readable() |
Ermittelt ob eine Datei lesbar ist |
is_writeable() |
Ermittelt, ob in eine Datei geschrieben werden kann |
link() |
Erzeugt einen absoluten Link |
linkinfo() |
Ermittelt Informationen über einen Link |
lstat() |
Ermittelt Informationen über einen symbolischen Link |
mkdir() |
Erstellt ein Verzeichnis |
pclose() |
Schließt einen Prozess-Dateizeiger |
popen() |
Öffnet einen Prozesszeiger |
readfile() |
Gibt eine Datei aus |
readlink() |
Gibt das Ziel eines symbolischen Links zurück |
rename() |
Benennt eine Datei um |
rewind() |
Setzt den Dateizeiger auf das erste Byte der Datei |
rmdir() |
Löscht ein Verzeichnis |
set_file_buffer() |
Setzt die Dateipufferung für einen gegebenen Dateizeiger |
stat() |
Ermittelt diverse Informationen über eine Datei |
symlink() |
Erzeugt einen symbolischen Link |
tempnam() |
Erzeugt einen eindeutigen Dateinamen |
touch() |
Setzt das Datum der letzten Änderung einer Datei |
umask() |
Ändert die aktuelle umask (Zugriffsrechte) |
unlink() |
Löscht eine Datei |
|