Dateien zu schreiben gehört zu den häufigsten Aufgaben in PHP. Ob Logdateien, Konfigurationen, Caches oder exportierte Daten: Irgendwann muss jede Anwendung Inhalte im Dateisystem ablegen. Die Funktion file_put_contents() erledigt das in einem einzigen Aufruf. Sie vereint das Öffnen, Schreiben und Schließen einer Datei und erspart den Umweg über fopen(), fwrite() und fclose(). In diesem Tutorial lernst du alle Parameter, die wichtigsten Flags wie FILE_APPEND und LOCK_EX sowie die richtige Fehlerbehandlung kennen.

Beginnen wir mit der grundlegenden Arbeitsweise der Funktion und ihrem Rückgabeverhalten.
Was macht file_put_contents()?
Die Funktion file_put_contents() schreibt einen String oder ein Array in eine Datei. Falls die Datei noch nicht existiert, wird sie automatisch erstellt. Falls sie bereits existiert, wird ihr Inhalt standardmäßig überschrieben. Der Rückgabewert ist die Anzahl der geschriebenen Bytes oder false bei einem Fehler.
<?php
$bytes = file_put_contents('beispiel.txt', 'Hallo Welt');
/* $bytes enthaelt die Anzahl geschriebener Bytes (10) */
echo $bytes;
Intern entspricht ein Aufruf von file_put_contents() dem manuellen Öffnen einer Datei mit fopen(), dem Schreiben mit fwrite() und dem Schließen mit fclose(). Die Funktion ist seit PHP 5 verfügbar und gehört zu den am häufigsten verwendeten Dateisystem-Funktionen.
Die Parameter im Detail
Die vollständige Signatur der Funktion lautet:
file_put_contents(string $filename, mixed $data, int $flags = 0, ?resource $context = null): int|false
Dateiname (filename)
Der erste Parameter gibt den Pfad zur Zieldatei an. Das kann ein relativer oder absoluter Pfad sein. Wenn die Datei nicht existiert, legt PHP sie automatisch an. Das Verzeichnis muss allerdings bereits vorhanden sein. PHP erstellt fehlende Verzeichnisse nicht automatisch. Vor dem Schreiben sollte daher mit is_dir() geprüft werden, ob der Zielordner existiert, und bei Bedarf mit mkdir() angelegt werden.
Daten (data) als String oder Array
Der zweite Parameter enthält die zu schreibenden Daten. Neben Strings akzeptiert die Funktion auch Arrays. Bei einem Array wird jedes Element nacheinander in die Datei geschrieben, vergleichbar mit implode('', $array). Außerdem kann eine Stream-Ressource übergeben werden, deren verbleibender Inhalt dann in die Datei kopiert wird.
Flags: FILE_APPEND und LOCK_EX
Der dritte Parameter steuert das Verhalten beim Schreiben. Die beiden wichtigsten Flags sind:
FILE_APPEND hängt die Daten an das Ende der Datei an, statt den vorhandenen Inhalt zu überschreiben.
LOCK_EX setzt eine exklusive Sperre auf die Datei, um gleichzeitige Schreibzugriffe durch andere Prozesse zu verhindern.
Mehrere Flags lassen sich mit dem Pipe-Operator kombinieren: FILE_APPEND | LOCK_EX.
Stream-Kontext (context)
Der vierte Parameter ist ein optionaler Stream-Kontext, der mit stream_context_create() erstellt wird. Er ermöglicht es, das Verhalten des Dateizugriffs zu beeinflussen, etwa bei der Arbeit mit entfernten Dateien über HTTP oder FTP. Für lokale Dateien wird dieser Parameter in der Regel nicht benötigt.
Dateien erstellen und überschreiben
Im Standardverhalten erstellt file_put_contents() eine neue Datei oder überschreibt eine bestehende vollständig. Das ist nützlich für Konfigurationsdateien, Cache-Dateien oder exportierte Daten, die bei jedem Aufruf neu generiert werden.
<?php
/* Verzeichnis pruefen und bei Bedarf erstellen */
$verzeichnis = __DIR__ . '/daten';
if (!is_dir($verzeichnis)) {
mkdir($verzeichnis, 0755, true);
}
/* Konfiguration als JSON in eine Datei schreiben */
$config = [
'app_name' => 'Meine Anwendung',
'version' => '2.1.0',
'debug' => false
];
$json = json_encode($config, JSON_PRETTY_PRINT);
$bytes = file_put_contents($verzeichnis . '/config.json', $json);
/* Ergebnis: Die Datei config.json wird erstellt oder ueberschrieben */
echo 'Geschrieben: ' . $bytes . ' Bytes';
Wird die Funktion erneut mit demselben Dateipfad aufgerufen, ersetzt der neue Inhalt den alten vollständig. Es gibt keine Warnung und keine Rückfrage. Deshalb sollte bei wichtigen Dateien vorher eine Sicherung erstellt oder das Anhängen mit FILE_APPEND verwendet werden.
Inhalte an eine Datei anhängen
Mit dem Flag FILE_APPEND werden neue Daten an das Ende der bestehenden Datei angehängt, anstatt den Inhalt zu überschreiben. Das ist besonders für Logdateien und Protokolle relevant.
<?php
$logDatei = __DIR__ . '/logs/anwendung.log';
$eintrag = sprintf(
'[%s] %s: %s' . PHP_EOL,
date('Y-m-d H:i:s'),
'INFO',
'Benutzer hat sich angemeldet'
);
file_put_contents($logDatei, $eintrag, FILE_APPEND);
/* Weitere Eintraege werden angehaengt, nicht ueberschrieben */
$fehler = sprintf(
'[%s] %s: %s' . PHP_EOL,
date('Y-m-d H:i:s'),
'ERROR',
'Datenbankverbindung fehlgeschlagen'
);
file_put_contents($logDatei, $fehler, FILE_APPEND);
Ohne FILE_APPEND würde der zweite Aufruf den ersten Eintrag überschreiben. Mit dem Flag bleiben alle bisherigen Einträge erhalten und die neue Zeile wird am Ende angefügt. Der Zeilenumbruch PHP_EOL muss manuell angehängt werden, da file_put_contents() keinen automatischen Zeilenumbruch einfügt.
Gleichzeitigen Dateizugriff absichern
Wenn mehrere Prozesse gleichzeitig in dieselbe Datei schreiben, können Daten verloren gehen oder beschädigt werden. Das Flag LOCK_EX setzt eine exklusive Sperre, sodass immer nur ein Prozess zur gleichen Zeit schreiben kann. Andere Prozesse warten, bis die Sperre freigegeben wird.
<?php
$zaehlerDatei = __DIR__ . '/zaehler.txt';
/* Aktuellen Stand lesen */
$stand = (int) @file_get_contents($zaehlerDatei);
$stand++;
/* Mit exklusiver Sperre zurueckschreiben */
file_put_contents($zaehlerDatei, (string) $stand, LOCK_EX);
/* FILE_APPEND und LOCK_EX kombinieren */
$logDatei = __DIR__ . '/zugriffe.log';
$zeile = date('Y-m-d H:i:s') . ' Seitenaufruf' . PHP_EOL;
file_put_contents($logDatei, $zeile, FILE_APPEND | LOCK_EX);
Die Kombination FILE_APPEND | LOCK_EX ist die sicherste Variante für Logdateien in Umgebungen mit mehreren gleichzeitigen Zugriffen. Die Sperre wird automatisch freigegeben, sobald der Schreibvorgang abgeschlossen ist.
flowchart TD
A["file_put_contents() aufrufen"] --> B{"Flags gesetzt?"}
B -->|"Keine Flags"| C["Datei oeffnen (ueberschreiben)"]
B -->|"FILE_APPEND"| D["Datei oeffnen (anhaengen)"]
B -->|"LOCK_EX"| E["Exklusive Sperre setzen"]
B -->|"FILE_APPEND | LOCK_EX"| F["Sperre setzen + anhaengen"]
C --> G["Daten schreiben"]
D --> G
E --> G
F --> G
G --> H["Datei schliessen"]
H --> I{"Erfolgreich?"}
I -->|"Ja"| J["Anzahl Bytes zurueckgeben"]
I -->|"Nein"| K["false zurueckgeben"]
Arrays in Dateien schreiben
Wird ein Array als zweiter Parameter übergeben, schreibt file_put_contents() jedes Element direkt nacheinander in die Datei. Das ist praktisch, um zeilenbasierte Dateien zu erzeugen, wenn die Elemente bereits Zeilenumbrüche enthalten.
<?php
/* Array mit Zeilenumbruechen in eine Datei schreiben */
$zeilen = [
'Erste Zeile' . PHP_EOL,
'Zweite Zeile' . PHP_EOL,
'Dritte Zeile' . PHP_EOL
];
file_put_contents(__DIR__ . '/liste.txt', $zeilen);
/* Ohne Zeilenumbrueche werden die Elemente direkt aneinandergehaengt */
$woerter = ['Hallo', ' ', 'Welt'];
file_put_contents(__DIR__ . '/woerter.txt', $woerter);
/* Ergebnis in der Datei: Hallo Welt */
Bei der Arbeit mit Arrays ist zu beachten, dass die Zeilenumbrüche nicht automatisch eingefügt werden. Jedes Array-Element muss den gewünschten Zeilenumbruch selbst enthalten. Alternativ lässt sich implode(PHP_EOL, $array) verwenden, um die Elemente vor dem Schreiben mit Zeilenumbrüchen zu verbinden.
Fehlerbehandlung und typische Probleme
Die Funktion file_put_contents() gibt bei einem Fehler false zurück. Da der Rückgabewert im Erfolgsfall die Anzahl geschriebener Bytes ist, kann dieser auch 0 sein, wenn ein leerer String geschrieben wird. Die Prüfung muss daher mit dem strikten Vergleichsoperator === erfolgen.
Permission Denied vermeiden
Der häufigste Fehler ist ein fehlendes Schreibrecht auf das Zielverzeichnis. Der Webserver-Prozess (z.B. www-data) benötigt Schreibrechte auf das Verzeichnis, in dem die Datei erstellt oder verändert werden soll. Unter Linux können die Rechte mit chmod und chown gesetzt werden. Außerdem scheitert der Schreibvorgang, wenn das Zielverzeichnis nicht existiert, da PHP fehlende Verzeichnisse nicht automatisch anlegt.
Rückgabewert prüfen
Die korrekte Prüfung unterscheidet zwischen false und 0:
<?php
$datei = __DIR__ . '/ausgabe.txt';
$inhalt = 'Wichtige Daten';
$ergebnis = file_put_contents($datei, $inhalt);
/* FALSCH: Diese Pruefung schlaegt auch bei 0 geschriebenen Bytes fehl */
if (!$ergebnis) {
echo 'Fehler beim Schreiben';
}
/* RICHTIG: Strikter Vergleich mit === */
if ($ergebnis === false) {
echo 'Fehler beim Schreiben der Datei';
} else {
echo $ergebnis . ' Bytes geschrieben';
}
/* Defensive Variante mit Verzeichnispruefung */
$zielVerzeichnis = dirname($datei);
if (!is_dir($zielVerzeichnis)) {
mkdir($zielVerzeichnis, 0755, true);
}
if (!is_writable($zielVerzeichnis)) {
echo 'Verzeichnis ist nicht beschreibbar: ' . $zielVerzeichnis;
} else {
$ergebnis = file_put_contents($datei, $inhalt, LOCK_EX);
if ($ergebnis === false) {
echo 'Schreibvorgang fehlgeschlagen';
}
}
In Produktionsumgebungen sollte zusätzlich der Error-Unterdrückungsoperator @ vermieden werden. Stattdessen ist es besser, Fehler mit error_log() zu protokollieren und dem Benutzer eine verständliche Fehlermeldung anzuzeigen.
file_put_contents vs. fopen/fwrite/fclose
Die Funktion file_put_contents() ist die Kurzform für die Kombination aus fopen(), fwrite() und fclose(). Für einfache Schreibvorgänge ist sie die bevorzugte Wahl, da der Code kürzer und lesbarer ist. Die manuelle Variante bietet jedoch mehr Kontrolle, etwa beim zeilenweisen Schreiben großer Datenmengen oder beim gleichzeitigen Lesen und Schreiben.
Ein Aufruf von file_put_contents('datei.txt', 'Inhalt', LOCK_EX) entspricht intern folgendem Ablauf:
<?php
/* Kurzform mit file_put_contents */
file_put_contents('datei.txt', 'Inhalt', LOCK_EX);
/* Entspricht dieser manuellen Variante */
$handle = fopen('datei.txt', 'w');
if ($handle !== false) {
flock($handle, LOCK_EX);
fwrite($handle, 'Inhalt');
flock($handle, LOCK_UN);
fclose($handle);
}
/* Die manuelle Variante ist sinnvoll bei grossen Dateien */
$handle = fopen('grosse_datei.csv', 'w');
if ($handle !== false) {
flock($handle, LOCK_EX);
foreach ($datensaetze as $zeile) {
fwrite($handle, implode(';', $zeile) . PHP_EOL);
}
flock($handle, LOCK_UN);
fclose($handle);
}
Für die meisten Anwendungsfälle ist file_put_contents() die richtige Wahl. Erst wenn Daten schrittweise geschrieben werden müssen oder die Dateigröße den verfügbaren Arbeitsspeicher übersteigt, lohnt sich der Umstieg auf fopen(), fwrite() und fclose().
Fazit
Die Funktion file_put_contents() ist das Standardwerkzeug zum Schreiben von Dateien in PHP. Sie erstellt neue Dateien automatisch, überschreibt bestehende Inhalte und unterstützt über Flags das Anhängen mit FILE_APPEND sowie die Absicherung gegen gleichzeitige Zugriffe mit LOCK_EX. Der Rückgabewert liefert die Anzahl geschriebener Bytes oder false bei einem Fehler, wobei die Prüfung immer mit dem strikten Operator === erfolgen muss. Für einfache Schreibvorgänge ersetzt sie die Kombination aus fopen(), fwrite() und fclose() durch einen einzigen, gut lesbaren Funktionsaufruf. Wer die Flags und die Fehlerbehandlung beherrscht, kann Dateien in PHP zuverlässig schreiben, anhängen und gegen konkurrierende Zugriffe absichern.