Dateisystem mit PHP

Mit PHP kann auf das Dateisystem eines Webservers direkt zugegrffen werden. Dateien können erstellt und gelöscht werden, in Dateien kann geschrieben und gelesen werden. Zusätzlich kann PHP auch auf die Verzeichnisse des Dateisystems zugreifen. Für die Arbeit mit Dateien und Verzeichnissen braucht man ausreichend Informationen über die vorliegenden Pfadstrukturen, einzelne Verzeichnisse und Dateien. PHP stellt Ihnen eine Reihe nützlicher Funktionen zur Verfügung, eine Liste der Datei- Verzeichnisfunktionen finden sie hier:

php.net/Verzeichnisfunktionen

php.net/Dateisystemfunktionen

Für Beispiele dieser Seite brauchen sie eine php-Datei z.B. index.php und eine Textdatei myText.txt.

Pfadangaben

Die meisten Funktionen erwarten eine Pfadangabe als Argument. Diese muss sich in der Regel auf eine existierende Datei beziehen. Den beiden Funktionen basename() und dirname() genügt ein String, der einen Pfad bezeichnet, ob Datei und Verzeichnis existieren, ist dabei nicht relevant.

Funktion Bedeutung
basename() Gibt letzten Namensteil einer Pfadangabe zurück. Unter Windows wird sowohl der Slash (/) als auch der Backslash (\) als Trennzeichen bei Pfadangaben benutzt. Unter anderen Betriebssystemen hingegen nur der Slash (/)
dirname() Aus einer übergebenen Zeichenkette, die den Pfad zu einer Datei oder einem Verzeichnis enthält, gibt diese Funktion den Pfad des übergeordneten Verzeichnisses zurück. Unter Windows wird sowohl der Slash (/) als auch der Backslash (\) als Trennzeichen bei Pfadangaben benutzt. Unter anderen Betriebssystemen hingegen nur der Slash (/)

Im folgenden Beispiel liefert basename myText.txt als Wert,
dirname liefert C:/adiprinz/php

<?php
echo basename("C:/adiprinz/php/myText.txt");
echo dirname("C:/adiprinz/php/myText.txt");
?>

Die folgenden Funktionen erwarten jedoch, dass der im Argument angegebene Pfad existiert.

Funktion Bedeutung
file_exists() Prüft, ob eine Datei oder ein Verzeichnis existiert (true or false)
filesize() Liefert die Größe einer Datei oder Fehler
filetype() Liefert den Typ einer Datei oder Fehler
is_dir() Prüft, ob der angegebene Dateiname ein Verzeichnis ist (true or false)
is_file() Prüft, ob der Dateiname eine reguläre Datei ist (true or false)
<?php
$file = file_exists("C:/adiprinz/php/myText.txt");
$size = filesize("C:/adiprinz/php/myText.txt");
$type = filetype("C:/adiprinz/php/myText.txt");
$isDir = is_dir("C:/adiprinz/php");
$isFile = is_file("C:/adiprinz/php/myText.txt");
?>

Die Funktionen eignen sich hervorragend für den Einsatz in if-Anweisungen.

<?php
if (is_dir("C:/adiprinz/php")) {
  echo "Verzeichnis ist vorhanden!";
}
?>

Die Pfadangaben dürfen keinen abschließenden Slash enthalten, z. B. C:/adiprinz/php/. Dies würde zu einer Fehlermeldung führen!

Relative und absolute Pfadangaben

Ein relativer Pfad ist relativ zum aktuellen Arbeitsverzeichnis des Benutzers oder der Anwendung. Um innerhalb dieses Arbeitsverzeichnisses zu agieren, müssen die vollständigen Pfade nicht mehr angegeben werden.

Ein absoluter Pfad zeigt unverwechselbar auf genau eine Stelle in einem Dateisystem, unabhängig von dem Arbeitsverzeichnis.

Verzeichnisse

Für die Verwaltung des Verzeichnissystems und dessen Manipulation stellt Ihnen PHP ebenfalls eine Reihe von Funktionen zur Verfügung.

Funktion Bedeutung
getcwd() Ermittelt das aktuelle Arbeitsverzeichnis oder false
mkdir() Erstellt ein Verzeichnis oder Fehler
rmdir() Löscht ein leeres Verzeichnis oder Fehler

Die Funktionen mkdir() legt ein neues Verzeichnis an, die Funktion rmdir() dagegen löscht Verzeichnisse. Auch diese beiden Funktionen beziehen sich, wenn keine vollständigen Pfade übergeben werden, auf das aktuelle Verzeichnis.

<?php
echo getcwd();
mkdir("myPHP",0700);
rmdir("myPHP");
?>

Beide Funktionen liefern bei fehlerfreier Ausführung den Wert true, andernfalls wird eine Fehlermeldung ausgegeben.

mkdir()

Die mkdir-Funktion kann bis zu vier Parameter aufnehmen. Die Syntax lautet:

mkdir(Pfad, Mode, Recursive)

Der erste Parameter ist das zu erstellende Verzeichnis. Bei meinen Tests hat eine verschachtelte Ordnerstruktur nur mit Recursive(true) funktioniert. Der zweite Parameter Mode bestimmt die Berechtigung und der dritte Parameter Recursive für verschachtelte Ordnerstrukturen.

<?php
$recursiv = 'Ordner1/Ordner2/Ordner3';
if (!mkdir($recursiv ,0777, true)) {
die('Erstellung der Verzeichnisse schlug fehl...');
}
?>

Berechtigung

Sowohl die Funktion chmod() als auch das zweite Argument der Funktion mkdir() ermöglichen die Vergabe von Berechtigungen für Dateien und Verzeichnisse. Diese Zahl setzt sich aus vier Stellen zusammen.

  • Die erste Stelle ist die Null, Berechtigungen werden im Oktal-Zahlenformat geschrieben
  • Die zweite Stelle stellt die Benutzerberechtigungen des Dateieigentümers dar
  • Die dritte Stelle steht für die Gruppenberechtigung und bestimmt, was Benutzer der Gruppe, der die Datei angehört, mit ihr machen können.
  • Die vierte Stelle steht für die globalen Berechtigungen und bestimmt, was alle Benutzer mit der Datei machen dürfen.

Der höchste Werte für die zweite, dritte und vierte Stelle ist sieben (7). Eine Berechtigung von 0777 ergibt somit volle Berechtigung für lesen, schreiben und ausführen der Datei bzw. Verzeichnisse.
Mehr Informationen über Berechtigungen finden sie hier:

php.net

Auslesen von Verzeichnissen

Zu den wichtigsten Aufgaben der Dateifunktionen gehört das Auslesen der Bestandteile eines Verzeichnisses. Für diese Aufgabe stehen mehrere Funktionen zur Verfügung.

Funktion Bedeutung
closedir(dir_handle) Löscht einen Verweis (Handle) auf ein Verzeichnis
dir(directory)) Liefert ein Objekt, das für ein Verzeichnis steht
opendir(path) Erzeugt einen Verweis (Handle) auf ein Verzeichnis
readdir(dir_handle) Ermittelt den jeweils nächsten Datei- oder Verzeichnisnamen aus einem Verzeichnis
rewinddir(dir_handle) Positioniert den readdir-Zeiger wieder auf dem ersten Eintrag eines Verzeichnisses
scandir(directory [, sorting_order]) Listet sämtliche Dateien und Verzeichnisse eines angegebenen Pfads auf. Die Sortierreihenfolge ist alphabetisch aufsteigend. Sollte der optionale Parameter sorting_order verwendet werden, wird die Sortierreihenfolge alphabetisch absteigend sein

Im Grunde verbergen sich hinter den oben vorgestellten Funktionen zwei Konzepte für den Zugriff auf Verzeichnisse und das Auslesen von Dateien:

Zugriff via Verweise

Einen Verweis liefert die Funktion opendir(). Das folgende Beispiel zeigt, wie Dateien aus einem Verzeichnis ausgelesen werden. Dieses Verzeichnis-Handle kann später für closedir() und readdir() genutzt werden.

<?php
// Öffnet aktuelles Verzeichnis
$handle = opendir('.');
echo "Verzeichnis-Handle: $handle <br>";
echo "Dateien: <br>";

while (false !== ($file = readdir($handle))) {
echo "$file <br>";
}
closedir($handle);
?>

readdir() liefert immer auch die Einträge "." und ".." zurück. Wollen sie das nicht, müssen sie ausgeschlossen werden..

<?php
$handle = opendir('.');
echo "Verzeichnis-Handle: $handle <br>";
echo "Dateien: <br>";

while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
echo "$file <br>";
}}
closedir($handle);
?>

Zugriff via Objekt

Kommen wir nun zum zweiten Konzept, nämlich dem Zugriff mithilfe des dir-Objekts. Es handelt sich hierbei um ein Pseudo-Objekt, d. h. eine Mischung aus Funktion und objektorientierter Lösung. Dem Objekt stehen diverse Eigenschaften und Methoden zur Verfügung, welche in folgender Tabelle aufgeführt sind:

Eigenschaft/Methode Bedeutung
handle Diese Eigenschaft liefert einen Verweis, welcher sich mit den weiter oben vorgestellten Funktionen nutzen lässt.
path Diese Eigenschaft liefert den Pfad des dir-Objekts.
close() Diese Methode gibt das Objekt wieder frei.
read() Diese Methode liefert bei jedem Aufruf den jeweils nächsten Verzeichniseintrag.
rewind() Diese Methode setzt den internen Zeiger für die read-Operationen wieder auf den ersten Eintrag.

Das Auslesen eines Verzeichnisses entspricht den bereits vorgestellten Beispielen. Lediglich die Syntax stellt sich etwas anders dar.

<?php
$verzeichnis = dir(".");
echo "Dateien: <br>";

while ($file = $verzeichnis->read()) {
echo "$file <br>";
}

$verzeichnis->close();
?>

Verarbeitung von Dateien

In diesem Abschnitt befassen wir uns mit der Verarbeitung von Dateien. Sie lernen Funktionen kennen, die es Ihnen ermöglichen, Dateien zu

Funktion Bedeutung
file(filename [, use_include_path]) Liest den Inhalt einer Datei in ein Array ein
readfile(filename [, use_include_path]) Liest den Inhalt einer Datei und schreibt ihn in den Ausgabepuffer
fopen(filename, mode [, use_include_path [, zcontext]]) Öffnet eine bestehende oder erzeugt eine neue Datei
fread(handle, length) Liest eine bestimmte Anzahl von Bytes aus einer Datei
fclose(handle) Schließt einen offenen Dateizeiger und damit auch die Datei
fgets(handle [, int length]) Liest eine Zeile von der Position des Dateizeigers
fwrite(handle, string [,length ] ) Schreibt den Inhalt der Zeichenkette string in die Datei, auf welche der Dateizeiger handle zeigt
feof( resource $handle ) Prüft, ob ein Dateizeiger am Ende der Datei steht

Einsatz von file() und readfile()

Mit dem Einsatz der Funktionen file() und readfile() kann PHP recht einfach auf den kompletten Inhalt einer Datei zuzugreifen. Die Funktion readfile() sendet den Inhalt direkt an den Browser und file() schreibt den Inhalt in ein Array.
Die folgende Anweisung reicht aus, um die Datei myText.txt im Browser anzuzeigen:

<?php
readfile("myText.txt");
?>

Die Funktion gibt im Erfolgsfall den Dateiinhalt aus. Sollte es nicht funktionieren, liefert sie den Wert false. Wenn auf eine Pfadangabe verzichtet wird, muss sich die Datei im selben Verzeichnis befinden wie das Skript, das die Anweisung enthält. Die Funktion eignet sich hervorragend zur Einbindung von HTML-Dateien.
Mit der Funktion file() kommen Sie ebenfalls an den Inhalt einer Datei. Der Inhalt wird als Array zurückgegeben.

<?php
$datei = file("myText.txt");

foreach($datei as $zeile) {
echo "$zeile <br>";
}
?>

$file() gibt die Datei in einem Array zurück. Jedes Element des Arrays entspricht einer Zeile in der Datei, ohne dass das Zeilenende entfernt wird. Im Fehlerfall gibt file() FALSE zurück.

Lesen und schreiben von Dateien

Um eine Datei zu öffnen, benötigt PHP die Funktion fopen(). Diese erwartet zwei Argumente:

  • Name der Datei
  • Dateiattribut

Die Funktion liefert als Rückgabewert einen Verweis (Handle) auf die Datei. Diesen Verweis benötigen sie für Lese- und Schreiboperationen, beispielsweise in Verbindung mit fread().

<?php
$datei = fopen("myText.txt","r");
echo fread($datei,1000);
fclose($datei);
?>

Dasselbe Beispiel nochmal, aber mit einer Fehlerbehandlung. Fehlermeldung wird unterdrückt und die eigene angezeigt.

<?php
@$datei = fopen("myText.txt", "r") or die("Kann myText.txt nicht öffnen!");
echo fread($datei, 1000);
fclose($datei);
?>

fread() liest eine bestimmte Anzahl von Bytes aus einer Datei, im Beispiel 1.000 Bytes. Das Dateiattribut, welches sich im zweiten Argument der fopen()-Funktion befindet, ist "r" und stellt die Datei lediglich zum Lesen zur Verfügung.

Modi von fopen()

In der folgenden Tabelle habe ich Ihnen die zur Verfügung stehenden Modi aufgelistet:

Modus Bedeutung
r Öffnet die Datei nur zum Lesen und positioniert den Dateizeiger auf den Anfang der Datei.
r+ Öffnet die Datei zum Lesen und Schreiben und setzt den Dateizeiger auf den Anfang der Datei.
w Öffnet die Datei nur zum Schreiben und setzt den Dateizeiger auf den Anfang der Datei sowie die Länge der Datei auf 0 Byte. Wenn die Datei nicht existiert, wird versucht sie anzulegen.
w+ Öffnet die Datei zum Lesen und Schreiben und setzt den Dateizeiger auf den Anfang der Datei sowie die Länge der Datei auf 0 Byte. Wenn die Datei nicht existiert, wird versucht sie anzulegen.
a Öffnet die Datei nur zum Schreiben. Positioniert den Dateizeiger auf das Ende der Datei. Wenn die Datei nicht existiert, wird versucht sie anzulegen.
a+ Öffnet die Datei zum Lesen und Schreiben. Positioniert den Dateizeiger auf das Ende der Datei. Wenn die Datei nicht existiert, wird versucht sie anzulegen.

Sie sollten vor allem auf die Angaben »w« und »w+« achten. Damit sind Sie in der Lage, Dateien zu löschen oder zu erzeugen. Die Angabe a (append) sollten Sie verwenden, wenn Sie an eine bereits bestehende Datei weitere Daten anhängen wollen.

Die folgende Tabelle soll Ihnen die Entscheidung für den einen oder anderen Modus beim Verarbeiten von Dateien erleichtern:

Modus Lesbar Schreibbar Dateizeiger Kürzen Erzeugen
r Ja Nein Anfang Nein Nein
r+ Ja Ja Anfang Nein Nein
w Nein Ja Anfang Ja Ja
w+ Ja Ja Anfang Ja Ja
a Nein Ja Ende Nein Ja
a+ Ja Ja Ende Nein Ja

Dateien von einem entfernten Server

Mit fopen() können auch Dateien von einem entfernten Server geöffnet werden wenn der Zugang mit http oder ftp erlaubt ist.

<?php
$datei = fopen("http://www.adiprinz.at/myText.txt","r");
?>

Um mithilfe von fopen() Dateien zu öffnen, die einen Benutzernamen und ein Passwort voraussetzen, platzieren Sie die Authentifizierungsinformationen wie folgt in die URL:

<?php
$datei = fopen("ftp://benutzername:passwort@ftp.adiprinz.at/php/myText.txt","r");
$datei = fopen("benutzername:passwort@http://www.adiprinz.at/myText.txt","r");
?>

Die Dateien werden mithilfe des URL-fopen-Wrapper übertragen. In der Standardkonfiguration ist dieser freigegeben, lässt sich jedoch durch die Option allow_url_fopen in Ihrer php.ini sperren.

Einsatz von fgets()

Neben dem bereits vorgestellten fread() stellt PHP zum Auslesen einer Datei auch noch fgets() zur Verfügung. Die beiden unterscheiden sich in einem wesentlichen Punkt: fread() liest immer so viele Zeichen, wie im zweiten Argument angegeben werden, fgets() liest nur bis zum nächsten Zeilenumbruch, auch wenn im zweiten Argument ein größerer Wert angegeben wurde.
fread() ignoriert beim Auslesen einer Datei die enthaltenen Zeilenumbrüche.

<?php
$datei = fopen("myText.txt","r");
echo fread($datei,1000);
fclose($datei);
?>

Das Beispiel oben liest den gesamten Inhalt von myText.txt, das Beispiel unten liest die erste Zeile von myText.txt.

<?php
$datei = fopen("myText.txt","r");
echo fgets($datei,1000);
fclose($datei);
?>

Bei jedem Aufruf von fgets() oder auch fread() wird der interne Dateizeiger an das Ende des eingelesenen Abschnitts gesetzt. Bei fgets() ist das in der Regel eine Zeile. Sollte jedoch eine Zeile länger sein als im zweiten Argument angegeben, wird lediglich ein Teil der Zeile eingelesen. Das heißt, dass fgets() bei jedem Aufruf eine Zeile weiter geht. Zum Auslesen aller Zeilen mit der Funktion fgets() bietet sich eine Schleife an, um nacheinander sämtliche Zeilen auszugeben.

<?php
$datei = fopen("myText.txt","r");
$zeile = true;
while ($zeile) {
  $zeile = fgets($datei, 1000);
  echo "$zeile <br>";
}
fclose($datei);
?>

Da fgets() ein Leerzeichen zurückgibt und dieses von der while-Schleife als false interpretiert wird, endet die Schleife automatisch, wenn in der Datei keine weiteren Zeilen vorkommen.

Die Funktion fgets() kann auch behilflich sein, eine Datei zu analysieren, wie beispielsweise die Anzahl der Zeilen zu ermitteln.

<?php
$zeilen = 0;
if ($datei = fopen("myText.txt","r")) {
while (!feof($datei)) {
if (fgets($datei, 1048576)) {
$zeilen++;
}}}
echo $zeilen;
fclose($datei);
?>

Der Wert für das zweite Argument in fgets() wurde bewusst so hoch gesetzt, um möglichst sämtliche Zeichen pro Zeile zu erfassen.

Sonderfall Datensätze

Eine Datei, welche datensatzähnliche Strukturen wie Trennzeichen aufweist, kann ebenfalls analysiert werden. Dafür muss im Text ein Zeichen oder String vorhanden sein, der als Trenner taugt. Im folgenden Beispiel ist es folgender String: -*-

<?php
$dsatz = 0;
$dsatz_trenner = '-*-';
if ($datei = fopen('myText.txt','r')) {
while (!feof($datei)) {
$z = rtrim(fgets($datei, 1048576));
if ($z == $dsatz_trenner) {
$dsatz++;
}}}
echo $dsatz;
fclose($datei);
?>

Bearbeiten einzelner Wörter einer Datei

Um mithilfe der Funktion fgets() einzelne Wörter bearbeiten bzw. erfassen zu können, müssen zusätzlich reguläre Ausdrücke z.B. mit der Funktion preg_split() verwendet werden.

<?php
$datei = fopen('myText.txt','r');
while (! feof($datei)) {
if ($z = fgets($datei,1048576)) {
// Zeile nach Wörtern durchsuchen
$worte = preg_split('/\s+/',$z,-1, PREG_SPLIT_NO_EMPTY);
// Alle Wörter einer Zeile bearbeiten
foreach ($worte as $wort) {
echo "$wort <br>";
}}}
fclose($datei);
?>

Der Code verwendet das Metazeichen \s der Regular Expression Engine. Hiermit werden Leerzeichen (Whitespaces) jeglicher Art verarbeitet, wie Leerzeichen, Tabulatoren, Zeilenvorschübe, Wagenrückläufe und Seitenvorschübe.

Erzeugen und Schreiben von Dateien

Eine neue Datei anzulegen bzw. eine bestehende Datei zu öffnen und darin zu schreiben ist mithilfe der Funktionen fopen() und fwrite() recht einfach.

<?php
$datei = fopen("myText.txt","w");
echo fwrite($datei, "Hallo Welt",100);
fclose($datei);
?>

Die fwrite()-Funktion gibt die Anzahl der Zeichen zurück, welche in die neue Datei myText.txt geschrieben wurden. Das letzte Argument von fwrite() ist übrigens optional:
Sollte die Anzahl der Zeichen aus der Zeichenfolge den Wert überschreiten, wird die Zeichenfolge auf den festgelegten Wert gekürzt. Zusätzlich ist zu beachten, dass fwrite() den internen Dateizeiger weitersetzt. Dieser steht nach der Ausführung hinter dem letzten geschriebenen Zeichen. Sollten Sie fwrite() erneut aufrufen, wird die neue Zeichenfolge an den vorhandenen Text angefügt.

In eine vorhandene Datei schreiben

Beim Schreiben in eine vorhandene Datei kommt es vor allem darauf an, mit welcher Zugriffsmethode die Datei geöffnet wird. Hierbei sind folgende Situationen zu unterscheiden:

  • Sie wollen weitere Daten an die Datei anfügen. In diesem Fall wählen Sie den Wert a (bzw. a+). Die Datei wird dann so geöffnet, dass ein schreibender Zugriff nur am Ende der Datei erfolgen kann
  • Sie wollen an einer beliebigen Stelle Daten in die Datei schreiben. Die an dieser Stelle befindlichen Daten werden dann jedoch überschrieben. In diesem Fall öffnen Sie die Datei mit der Einstellung r+. Der Dateizeiger steht dann am Anfang der Datei. Um an einer beliebigen Stelle zu schreiben, muss der Dateizeiger mit der Funktion fseek() positioniert werden
  • Sie wollen eine bestehende Datei ganz neu schreiben, also keine bestehenden Daten übernehmen. In diesem Fall wählen Sie den Zugriffsmodus w (bzw. w+). Im Grunde wird die Datei hierdurch gelöscht und mit dem gleichen Namen neu erzeugt

Die interessanteste Methode dürfte die zweite Variante sein. Hierbei handelt es sich um einen Zugriff auf eine bereits bestehende Datei, jedoch an einer beliebigen Stelle und nicht am Anfang oder am Ende der Datei. Hierfür benötigen Sie Funktionen, mit denen Sie die Position des Dateizeigers abfragen und setzen können. Diese habe ich in der folgenden Tabelle für Sie zusammengefasst:

Funktion Bedeutung
feof (handle) Prüft, ob der Dateizeiger am Ende der Datei steht.
fseek (handle, offset [,postion]) Positioniert den Dateizeiger auf eine beliebige Stelle innerhalb der Datei.
ftell (handle) Ermittelt die aktuelle Position des Dateizeigers.
rewind(handle) Positioniert den Dateizeiger an den Anfang der Datei.

Im folgenden Beispiel öffnet $datei die Datei myText.txt im Lese- und Schreibmodus, der Zeiger wird an die oberste Position gestellt (r+). $zeiger1 liefert die aktuelle Zeigerposition (0). fwrite schreibt den Text "Hallo Welt!", vorhandener Text wird dabei überschrieben. $zeiger2 liefert die neu aktuelle Zeigerposition (11).

<?php
$datei = fopen("myText.txt","r+");
$zeiger1 = ftell($datei);
echo  $zeiger1 . "<br>"; // 0
fwrite($datei, "Hallo Welt!");
$zeiger2 = ftell($datei);
echo  $zeiger2; // 11
fclose($datei);
?>

fopen öffnet die Datei myText.txt im Lesemodus. fgets findet Bytes -1 der ersten Zeile (falls vorhanden). ftell setzt den Zeiger fgets-1.

Die Funktion fseek()

Die Funktion fseek() benötigt einen offset (Versatzwert), um den Dateizeiger ausgehend von einer festgelegten Position neu zu positionieren. Auf welche Startposition sich der Versatz bezieht, bestimmen Sie im letzten Argument. Dieses Argument ist optional. Wenn Sie darauf verzichten, zählt der Versatzwert vom Anfang der Datei. Die Startposition lässt sich mithilfe einer der folgenden Konstanten bestimmen:

  • SEEK_SET – Als Startposition wird der Dateianfang angenommen. Der Versatzwert steht dann auch für die absolute Position. Diese Konstante entspricht dem Standardwert und muss daher nicht unbedingt angegeben werden
  • SEEK_CUR – Als Startposition wird die aktuelle Position angenommen. Der Versatzwert bezieht sich dann auf diese Position
  • SEEK_END – Als Startposition wird das Dateiende angenommen. Das bedeutet, dass der Dateizeiger auch nach dem eigentlichen Ende der Datei positioniert werden kann. Diese Eigenschaft macht es möglich, eine strukturierte Datei mit Datensätzen fester Länge zu erzeugen. Die Datei muss hierzu nicht mit SEEK_END geöffnet werden

Die aktuelle Position kann mit der Funktion ftell() ausgelesen werden. Das folgende Beispiel kombiniert beide Funktionen und stellt die relative Positionierung mit SEEK_CUR dar.

<?php
$datei = fopen("myText.txt","r+");
fseek($datei, 50);
echo ftell($datei) . "<br>";
fseek($datei, 15, SEEK_CUR);
echo ftell($datei) . "<br>";
fwrite($datei, "Hallo Welt!");
echo ftell($datei) . "<br>";
fclose($datei);
?>

Die Datei wurde mit dem Zugriffsmode r+ geöffnet. Der Dateizeiger lässt sich dann auch für das Schreiben frei positionieren. Wenn hingegen den Modus a (bzw. a+) verwendet wird,, werden sämtliche Daten an das Ende der Datei angefügt, unabhängig davon, wo gerade der Dateizeiger steht. Die Positionierung mit fseek() kann dann lediglich für das Auslesen benutzt werden.

Kopieren, Umbenennen und Löschen von Dateien

Zusätzlich zu den bisherigen Funktionen stehen noch die Funktionen copy(), rename() und unlink() zur Verfügung, mit deren Hilfe Dateien kopiert, umbenannt und gelöscht werden.

Funktion Bedeutung
copy(source ,dest) Kopiert Datei source nach dest (true or false)
rename(oldname ,newname) Versucht oldname in newname umzubenennen, wobei bei Bedarf zwischen Verzeichnissen verschoben wird. Existiert newname bereits, wird es überschrieben (true or false)
unlink(filename) Löscht filename oder Fehler

Kopieren

<?php
if (@copy("myText.txt", "daten.txt")) {
echo "Kopiert";
} else {
echo "Fehler!";
}
?>

Umbenennen - Verschieben

<?php
if (@rename("daten.txt", "datenumbenannt.txt")) {
echo "Umbenannt";
} else {
echo "Fehler!";
}
?>

Löschen

<?php
if (@unlink("datenumbenannt.txt")) {
echo "Gelöscht";
} else {
echo "Fehler!";
}
?>

Weitere Einsatzgebiete

Funktionen wie file() oder file_get_contents() sorgen dafür, dass der Inhalt einer Datei eingelesen wird.

Einsatz von serialize() und unserialize()

Eine Variable (z.B. ein Array) kann mithilfe von serialize() in ein speicherbares Format übertragen werden. Beim Auslesen werden diese Daten wieder deserialisiert.

Funktion Bedeutung
serialize(value) Erzeugt eine speicherbare Repräsentation eines Wertes
unserialize(value) Erzeugt aus einem gespeicherten Datenformat einen Wert in PHP

Die serialize()-Funktion gibt eine Zeichenfolge zurück, die eine einem Byte-Stream entsprechende Wiedergabe von einer Variablen enthält und beliebig abgespeichert werden kann. Diese Funktion dient der Speicherung oder Übergabe von PHP-Werten, ohne dass diese ihren Wert oder ihre Struktur verlieren.

<?php
$personen = array(
"Adi", "Gabi", "Harald");
$daten = serialize($personen);
echo $daten;
// liefert a:3:{i:0;s:3:"Adi";i:1;s:4:"Gabi";i:2;s:6:"Harald";} 
?>

Eine solche Zeichenfolge kann mithilfe der Funktion unserialize(), wieder in eine gültige Variable umgewandelt werden.

<?php
$daten = 'a:3:{i:0;s:3:"Adi";i:1;s:4:"Gabi";i:2;s:6:"Harald";}';
$personen = unserialize($daten);
echo "<pre>";
print_r ($personen);
echo "</pre>";
/* liefert:
Array
(
    [0] => Adi
    [1] => Gabi
    [2] => Harald
)
*/
?>

Verriegelung von Dateien

Jeder Schreibvorgang innerhalb einer Webanwendung birgt das Risiko, dass Daten überschrieben werden. Ein Verriegelungsverfahren davor schützt, dass Inhalte einer Datei nicht ungewollt verändert werden können.

Eine Datei wird hierbei durch einen Lock geschützt. Dieses Verfahren sperrt eine Datei, sodass ein ungewollter Zugriff ausgeschlossen werden kann. Die Funktion für die Verriegelung heißt flock().

Funktion Bedeutung
flock(handle, operation) Erlaubt, ein einfaches Leser/Schreiber Modell umzusetzen

Diese Funktion erwartet neben dem Datei-Handler als zweites Argument einen Integerwert für die durchzuführende Verriegelungsoperation. Dabei stehen folgende Verriegelungs-Konstanten zur Verfügung:

Konstante Wert Bedeutung
LOCK_SH 1 lock shared, verteilt lesende Verriegelung, andere Prozesse können lesend zugreifen.
LOCK_EX 2 lock exclusive, keinem anderen Prozess den Zugriff ermöglichen.
LOCK_UN 3 lock unlock, Verriegelung aufheben, sowohl lesend als auch schreibend.
LOCK_NB 4 lock non-blocking, in Verbindung mit LOCK_EX und LOCK_UN, beendet den Zugriffsversuch, ohne zu warten, bis die Datei für Zugriffe frei ist.

Um eine Datei zu sperren, benötigt die Funktion einen Datei-Handler, den Sie mit fopen() erhalten. Als Operation können Sie entweder einen verteilten oder einen exklusiven Zugriff erlauben oder eine Verriegelung wieder aufheben. Die Option LOCK_NB legt fest, wie reagiert werden soll, wenn eine Datei gesperrt vorgefunden wird. Um dies anzugeben, notieren Sie nach der Operation einen senkrechten Strich und danach die Konstante. Sie sollten diese nur dann einsetzen, wenn Sie Zugriffe während der Verriegelung durch flock() zulassen wollen.

Der Einsatz einer Verriegelung macht jedoch nur dann Sinn, wenn alle Programme die gleiche Art und Weise der Verriegelung nutzen. Eine Verriegelung von Dateien wird im Übrigen lediglich empfohlen. Solange Sie kein flock() verwenden, um den Verriegelungsstatus einer Datei festzulegen, können Sie auf diese bequem Lese-/Schreibzugriffe ausführen.

<?php
$datei = fopen("myText.txt","w+");
// exclusive lock
if (flock($datei,LOCK_EX))
{
fwrite($datei,"Hallo Welt!");
// release lock
flock($datei,LOCK_UN);
} else {
echo "Error locking file!";
}
fclose($datei);
?>

Auslesen von CSV-Dateien

Abschließend wird noch die Funktion fgetcsv() vorgestellt. Vorab jedoch noch eine kurze Einführung in die Struktur von CSV-Dateien (comma separated values). Hierbei handelt es sich um Textdateien, deren Einträge in Zeilen und Spalten (Felder) unterteilt sind. Die Zeilen werden durch Zeilenumbrüche gekennzeichnet und die Felder durch Kommata oder andere Trennzeichen. Für das Auslesen solcher Dateien können Sie die Funktion fgetcsv() einsetzen. Die Funktion erwartet eine Textdatei, die beispielsweise wie folgt strukturiert ist:

1, erster Mitarbeiter, Adi, Prinz
2, zweiter Mitarbeiter, Gabi, Prinz

Jeder Aufruf von fgetcsv() liefert die jeweils nächste Zeile. Die Funktion benötigt mindestens zwei Argumente:

  • Dateihandle
  • Maximale Anzahl der auszulesenden Zeichen
<?php
$datei = fopen("myText.txt", "r");
$daten = fgetcsv($datei, 1000);
while ($daten) {
echo implode(" – ", $daten) . "<br>";
$daten = fgetcsv($datei, 1000);
}
/* liefert:
1 – erster Mitarbeiter – Adi – Prinz
2 – zweiter Mitarbeiter – Gabi – Prinz
*/
?>