Signatur
Beschreibung
fsync() sorgt dafür, dass alle in den Betriebssystem-Puffern gehaltenen Schreiboperationen für den angegebenen Stream tatsächlich auf das zugrunde liegende Speichermedium übertragen werden – einschließlich Metadaten wie Zeitstempel und Dateiattribute. Die Funktion kehrt erst zurück, wenn das Gerät die erfolgreiche Speicherung bestätigt hat.
Dies ist besonders in Szenarien wichtig, bei denen ein Systemabsturz oder Stromausfall keine Datenverluste hinterlassen darf – etwa beim Schreiben von Transaktions-Logs, Konfigurationsdateien oder kritischen Nutzerdaten. Ohne fsync() kann das Betriebssystem Schreibvorgänge noch minutenlang im Cache halten.
Im Unterschied zu fflush(), das nur den PHP-internen Puffer in den Betriebssystem-Puffer leert, leert fsync() zusätzlich den Kernel-Puffer und wartet auf die physische Speicherbestätigung des Laufwerks. Für Metadaten-Synchronisation ohne Garantie auf Metadaten steht außerdem fdatasync() zur Verfügung.
Der Aufruf kann je nach Speichermedium und Datenmenge spürbar Zeit kosten, da auf das langsamere Schreiben von HDD/SSD gewartet wird. Er sollte daher gezielt eingesetzt werden, etwa nach dem vollständigen Schreiben einer Datei, und nicht innerhalb enger Schleifen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $stream Pflicht | resource | Ein mit fopen() oder einer ähnlichen Funktion geöffnetes Datei-Handle, das für das Schreiben geöffnet sein muss. |
Rückgabewert
true zurück, wenn die Synchronisation erfolgreich war, andernfalls false. Im Fehlerfall (z. B. ungültiger Stream oder Gerätfehler) wird false zurückgegeben.Beispiele
Kritische Konfigurationsdatei sicher auf Disk schreiben
<?php
$file = '/var/app/config/settings.json';
$data = json_encode(['version' => 2, 'debug' => false], JSON_PRETTY_PRINT);
$handle = fopen($file, 'w');
if ($handle === false) {
throw new RuntimeException('Datei konnte nicht geöffnet werden.');
}
fwrite($handle, $data);
// Zuerst PHP-internen Puffer in den Kernel-Puffer leeren
fflush($handle);
// Dann Kernel-Puffer auf das Speichermedium synchronisieren
if (!fsync($handle)) {
throw new RuntimeException('fsync() fehlgeschlagen – Daten möglicherweise nicht gespeichert.');
}
fclose($handle);
echo "Konfiguration erfolgreich und sicher gespeichert.\n";
Transaktions-Log mit garantierter Haltbarkeit schreiben
<?php
function writeTransactionLog(string $logFile, array $entry): void {
$handle = fopen($logFile, 'a');
if ($handle === false) {
throw new RuntimeException('Log-Datei konnte nicht geöffnet werden.');
}
$line = date('Y-m-d H:i:s') . ' | ' . json_encode($entry) . PHP_EOL;
fwrite($handle, $line);
// Sicherstellen, dass der Log-Eintrag dauerhaft gespeichert ist
fflush($handle);
fsync($handle);
fclose($handle);
}
writeTransactionLog('/var/log/transactions.log', [
'type' => 'PAYMENT',
'amount' => 49.99,
'status' => 'SUCCESS',
]);
echo "Log-Eintrag dauerhaft gespeichert.\n";
// Wichtig · Fallstricke
Performance: fsync() ist ein teurer Systemaufruf, weil er auf das physische Speichermedium wartet. Auf Systemen mit rotierenden Festplatten kann dies mehrere Millisekunden dauern. Bei SSDs ist der Overhead geringer, aber dennoch vorhanden. Den Aufruf daher nur für wirklich kritische Daten verwenden.
Verfügbarkeit: fsync() ist seit PHP 8.1.0 verfügbar. Für ältere PHP-Versionen gibt es keine native Entsprechung; ein Workaround wäre der Einsatz von fflush() (ohne Kernel-Garantie) oder das Aufrufen des C-Systemaufrufs über eine FFI-Extension.
Windows: Auf Windows entspricht die Implementierung dem FlushFileBuffers()-Aufruf, der ein vergleichbares Verhalten wie POSIX fsync() bietet.
Reihenfolge: Es empfiehlt sich, vor fsync() immer fflush() aufzurufen, damit der PHP-interne Ausgabepuffer zuerst in den Kernel-Puffer übertragen wird.