Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Lernpfade
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 Unit Test Generator
 TLD Liste
 Webkatalog‑Verzeichnis

Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains...
https://www.Hosterplus.de
Artfiles.de
Bietet Serviceorientierte...
https://www.Artfiles.de
 
 
 

PHP fopen(): Dateien öffnen, lesen und schreiben

Sie befinden sich: Home > Php Tutorial > PHP fopen(): Dateien öffnen...

PHP fopen(): Dateien öffnen, lesen und schreiben
Eintrag am:
10.08.2026
Hits / Besucher:
5
Sprache:
  Deutsch
Tutorial Art:
eigenes
Eingetragen von:
Merkliste:
 
Beschreibung

Eine Protokolldatei soll um eine Zeile wachsen, nicht neu beginnen. Eine Lieferantenliste mit 800 MB soll verarbeitet werden, ohne dass der Arbeitsspeicher voll läuft. Beides sind Aufgaben, bei denen die kurzen Wege nicht mehr reichen und ein offener Zugriffspunkt auf die Datei gebraucht wird.

Illustration zum Tutorial: PHP fopen(): Dateien öffnen, lesen und schreiben

Das Bild zeigt, worum es geht: aus einer Datei wird ein Handle, und der Modus entscheidet, was damit erlaubt ist. Genau dort beginnt dieses Tutorial.

Was PHP fopen() macht

Die Signatur lautet fopen(string $filename, string $mode, bool $use_include_path = false, $context = null). Zurück kommt eine Stream-Ressource oder false. Diese Ressource ist der Handle, also der Zugriffspunkt, über den alle weiteren Funktionen arbeiten.

<?php

$fp = fopen('daten/notizen.txt', 'r');

if ($fp === false) {
exit('Datei laesst sich nicht oeffnen.');
}

$erste = fgets($fp);
echo $erste;

fclose($fp);

Wichtig ist der zweite Blick auf den Rückgabewert. PHP fopen wirft keine Ausnahme, wenn etwas schiefgeht, sondern liefert false und dazu eine Warnung. Ein try mit catch fängt hier also nichts ab. Geprüft wird der Rückgabewert, und zwar mit ===, weil eine Ressource in einem lockeren Vergleich unerwartete Ergebnisse liefern kann.

fopen() oder file_get_contents()? Die Entscheidungsregel

Diese Frage steht am Anfang jeder Dateiarbeit, deshalb kommt sie hier so weit vorn. file_get_contents() und file() holen den kompletten Inhalt in einem Zug und sind danach fertig. PHP fopen gibt stattdessen einen Handle zurück, der offen bleibt, bis er geschlossen wird. Genau deshalb lässt sich damit schrittweise lesen, mittendrin springen, sperren und weiterschreiben.

Die Arbeitsteilung ergibt sich daraus fast von selbst. Eine kleine Konfigurationsdatei, die vollständig gebraucht wird, holt man mit der Kurzform. Eine große Datei, ein paralleler Zugriff oder ein gezielter Teilbereich verlangen nach dem Handle. Wer eine Datei zeilenweise in ein Array einlesen will, findet in PHP file() für das zeilenweise Einlesen in ein Array den passenden kurzen Weg, und zum reinen Schreiben führt PHP file_put_contents() zum Schreiben und Anhängen schneller zum Ziel.

Die Modi von PHP fopen() in der Übersicht

Der Modus ist die Stelle, an der die teuren Fehler passieren. Ein einziger falscher Buchstabe löscht den Bestand einer Woche. Drei Fragen beantwortet jeder Modus: Wird die vorhandene Datei geleert? Wird sie angelegt, wenn sie fehlt? Und wo steht der Zeiger nach dem Öffnen?

Modus Erlaubt Leert die Datei Legt sie an Zeiger startet
rnur lesenneinneinam Anfang
r+lesen und schreibenneinneinam Anfang
wnur schreibenja, sofortjaam Anfang
w+lesen und schreibenja, sofortjaam Anfang
aanhängenneinjaam Ende
a+lesen und anhängenneinjaam Ende
xnur schreibenneinja, sonst falseam Anfang
cnur schreibenneinjaam Anfang

Ein b lässt sich an jeden dieser Modi anhängen und schaltet in den Binärmodus. Warum das keine Kleinigkeit ist, klärt der vorletzte Abschnitt. Zwei Eigenheiten verdienen schon hier eine Erwähnung: Im Anhängemodus landet jeder Schreibvorgang am Dateiende, auch wenn der Zeiger vorher woanders stand. Und x ist der einzige Modus, der eine vorhandene Datei schützt, statt sie zu überschreiben.

Eine Datei mit PHP fopen() zeilenweise lesen

Die Leseschleife ist das Arbeitspferd. Sie holt immer nur eine Zeile in den Speicher, verarbeitet sie und vergisst sie wieder.

<?php

$fp = fopen('daten/lieferanten.csv', 'rb');

if ($fp === false) {
exit('Datei nicht lesbar.');
}

$nummer = 0;

while (!feof($fp)) {
$zeile = fgets($fp);

if ($zeile === false) {
break;
}

$nummer++;
echo $nummer . ': ' . rtrim($zeile, "\r\n") . PHP_EOL;
}

fclose($fp);

Zwei Details sind wichtig. feof() meldet das Dateiende erst, nachdem ein Lesevorgang darüber hinausgegangen ist, deshalb steht die zusätzliche Prüfung auf false im Rumpf. Und rtrim() entfernt den Zeilenumbruch, den fgets() mitliefert. Wer sich für die Feinheiten des zeilenweisen Lesens interessiert, findet sie in Dateien zeilenweise lesen mit fgets().

Speicherverbrauch: PHP fopen() gegen file()

Der Unterschied lässt sich messen, und die Zahlen sind deutlich. Beide Varianten verarbeiten dieselbe Datei von rund 190 MB.

<?php

/* Variante 1: alles auf einmal */
$zeilen = file('daten/gross.csv');
echo count($zeilen) . ' Zeilen, Spitze: ';
echo round(memory_get_peak_usage(true) / 1048576) . ' MB';
/* rund 190 Zeilen-Array plus Overhead, Spitze deutlich ueber 200 MB */

/* Variante 2: Zeile fuer Zeile */
$fp = fopen('daten/gross.csv', 'rb');
$anzahl = 0;

while (($zeile = fgets($fp)) !== false) {
$anzahl++;
}

fclose($fp);
echo $anzahl . ' Zeilen, Spitze: ';
echo round(memory_get_peak_usage(true) / 1048576) . ' MB';
/* Spitze bleibt im einstelligen MB-Bereich */

Die erste Variante hält jede Zeile als eigenen Eintrag im Arbeitsspeicher, die zweite immer nur eine. Deshalb wächst der Bedarf bei der Schleife nicht mit der Dateigröße. Das ist der eigentliche Grund, warum PHP fopen bei großen Dateien alternativlos ist.

Wenn PHP fopen() fehlschlägt

Die Meldung failed to open stream gehört zu den häufigsten überhaupt. Sie hat in aller Regel eine von drei Ursachen.

Der Pfad stimmt nicht Relative Pfade beziehen sich auf das Arbeitsverzeichnis des Prozesses, nicht auf den Ordner der Skriptdatei. getcwd() zeigt, wo PHP gerade steht, __DIR__ liefert einen verlässlichen Ausgangspunkt.
Die Rechte fehlen is_readable() und is_writable() beantworten das vor dem Öffnen. Beim Webserver zählen die Rechte des Serverbenutzers, nicht die des eigenen Kontos.
Das Verzeichnis existiert nicht PHP fopen legt niemals Verzeichnisse an, auch nicht in den schreibenden Modi. Dafür ist PHP mkdir zum Erstellen von Verzeichnissen zuständig.

Was in dieser Lage nicht hilft, ist das Unterdrücken der Warnung mit einem vorangestellten @. Der Rückgabewert bleibt false, der Fehler tritt eine Zeile später auf, und die Meldung, die den Weg gewiesen hätte, ist weg. Sinnvoll ist das Gegenteil: prüfen, abbrechen und eine verständliche eigene Meldung ausgeben.

Mit PHP fopen() schreiben und anhängen

Der Unterschied zwischen w und a entscheidet darüber, ob eine Datei wächst oder jeden Tag neu beginnt.

<?php

/* Anhaengen: der Bestand bleibt stehen */
$fp = fopen('logs/zugriffe.log', 'a');
fwrite($fp, date('Y-m-d H:i:s') . " Aufruf\n");
fclose($fp);

/* Zum Vergleich: w leert die Datei beim Oeffnen,
noch bevor ueberhaupt etwas geschrieben wurde. */
$fp = fopen('logs/zugriffe.log', 'w');
/* Die Datei ist an dieser Stelle bereits leer. */
fclose($fp);

Der zweite Block ist der klassische Datenverlust. Das Leeren passiert beim Öffnen, nicht beim Schreiben. Selbst wenn das Skript danach abbricht, ist der alte Inhalt fort. Wer eine vorhandene Datei ausdrücklich nicht überschreiben will, nimmt x: Existiert sie schon, liefert der Aufruf false, ohne etwas anzurühren.

Paralleles Schreiben absichern

Sobald zwei Prozesse dieselbe Datei beschreiben, reicht der richtige Modus allein nicht mehr. Es braucht eine Sperre, und die Reihenfolge ist entscheidend.

<?php

/* c oeffnet zum Schreiben, ohne zu leeren.
Damit steht die Sperre, bevor Daten verloren gehen koennen. */
$fp = fopen('daten/zaehler.txt', 'c');

if ($fp === false) {
exit('Kein Zugriff.');
}

if (flock($fp, LOCK_EX)) {
$wert = (int) stream_get_contents($fp);
$wert++;

ftruncate($fp, 0);
rewind($fp);
fwrite($fp, (string) $wert);
fflush($fp);
flock($fp, LOCK_UN);
}

fclose($fp);

Mit w wäre dieser Ablauf kaputt, denn die Datei wäre bereits leer, bevor flock() überhaupt zum Zuge kommt. Ein zweiter Prozess würde dann eine halb geschriebene Datei vorfinden. Die Feinheiten der Sperren behandelt PHP flock() für sicheres paralleles Schreiben.

Mehr als Dateien: Wrapper und der Binärmodus

Der erste Parameter muss kein Dateipfad sein. PHP fopen versteht auch Adressen wie http://, ftp://, php://memory oder php://temp. Besonders die letzten beiden sind nützlich, weil sie sich wie eine Datei verhalten, ohne dass eine angelegt wird.

<?php

$fp = fopen('php://temp', 'r+');

fwrite($fp, "Erste Zeile\nZweite Zeile\n");
rewind($fp);

echo stream_get_contents($fp);
/* Erste Zeile
Zweite Zeile */

fclose($fp);

Das rewind() ist Pflicht, denn nach dem Schreiben steht der Zeiger am Ende und es gäbe nichts mehr zu lesen. Bei den Netzwerk-Wrappern gilt eine Einschränkung: Ist allow_url_fopen in der Serverkonfiguration abgeschaltet, funktioniert der Zugriff auf HTTP-Adressen nicht. Für Anfragen über das Netz ist cURL ohnehin die bessere Wahl, weil sich dort Zeitlimits, Kopfzeilen und Statuscodes auswerten lassen.

Das angehängte b schaltet in den Binärmodus. Unter Windows wandelt der Textmodus einen Zeilenumbruch beim Schreiben in zwei Zeichen um, was bei Bildern, ZIP-Archiven oder PDF-Dateien den Inhalt zerstört. Unter Linux ist das Flag wirkungslos. Daraus folgt eine einfache Regel: b immer setzen, es schadet nie.

Warum fclose() dazugehört

PHP gibt offene Handles am Skriptende automatisch frei. Das stimmt, taugt aber nur für kurze Anfragen als Begründung. Ein Worker-Prozess, der stundenlang läuft und in jedem Durchgang eine Datei öffnet, sammelt Handles an, bis das Systemlimit erreicht ist. Dann schlägt jedes weitere PHP fopen fehl, und zwar an einer Stelle, die mit der Ursache nichts zu tun hat.

Dazu kommt der Schreibpuffer. Erst fclose() oder fflush() stellt sicher, dass die Daten tatsächlich auf dem Datenträger stehen und nicht nur im Zwischenspeicher.

flowchart TD
  A[fopen mit Modus] --> B{Handle oder false}
  B -->|false| C[Ursache pruefen]
  B -->|Handle| D{Lesen oder Schreiben}
  D -->|Lesen| E[fgets in Schleife]
  D -->|Schreiben| F[flock dann fwrite]
  E --> G[fclose]
  F --> G[fclose]

Das Diagramm fasst den Ablauf zusammen: erst prüfen, dann arbeiten, am Ende schließen. Jeder Zweig endet beim selben Aufruf.

Fazit

PHP fopen ist der Einstieg in jede Dateiarbeit, die mehr verlangt als ein einmaliges Lesen oder Schreiben. Der Handle erlaubt schrittweises Arbeiten, und genau das hält den Speicherbedarf unabhängig von der Dateigröße. Wer den Modus bewusst wählt statt aus Gewohnheit, vermeidet den häufigsten Datenverlust überhaupt. Und wer bei einer Fehlermeldung zuerst Pfad, Rechte und Verzeichnis prüft, statt die Warnung zu unterdrücken, findet die Ursache meist in einer Minute.

 

Tags:

 

 

Kommentare (0)

Noch keine Kommentare. Sei der Erste!

Melde dich an, um einen Kommentar zu schreiben.
Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.