Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Push Meldungen
 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

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

PHP fstat(): Dateiinformationen am offenen Handle lesen

Sie befinden sich: Home > Php Tutorial > PHP fstat(): Dateiinformati...

PHP fstat(): Dateiinformationen am offenen Handle lesen
Veröffentlicht am:
14.09.2026
Hits / Besucher:
4
Sprache:
  Deutsch
Tutorial Art:
eigenes
Eingetragen von:
Merkliste:
 
Beschreibung

Ein Portal nimmt große Bewerbungsunterlagen entgegen und prüft vor der Verarbeitung die Dateigröße. Zwischen dieser Prüfung und dem Öffnen liegt ein kurzer Moment, in dem sich die Datei ändern kann. Genau für diesen Moment gibt es eine eigene Funktion.

Illustration zum Tutorial: PHP fstat(): Dateiinformationen am offenen Handle lesen

Im Bild hängt die Eigenschaftsliste direkt an der geöffneten Datei, nicht am Dateinamen. Dieser Unterschied ist der Kern des Themas.

Was PHP fstat() liefert

PHP fstat() gibt Informationen zu einer Datei zurück, die bereits geöffnet ist. Der Aufruf bekommt kein Verzeichnis und keinen Dateinamen, sondern das Handle aus fopen(). Zurück kommt ein Array mit dreizehn Werten, von der Größe über die Zeitstempel bis zur Inode-Nummer.

<?php

$handle = fopen('/var/www/upload/lebenslauf.pdf', 'rb');
$daten = fstat($handle);

echo $daten['size']; // 284915
echo date('d.m.Y H:i', $daten['mtime']); /* 10.08.2026 09:12 */

fclose($handle);

Der Unterschied zu filesize() klingt nach einer Kleinigkeit und ist keine. PHP filesize() und disk_free_space() zum Prüfen von Dateigrößen arbeitet mit dem Pfad und beantwortet die Frage "wie groß ist die Datei, die gerade unter diesem Namen liegt". PHP fstat() beantwortet die Frage "wie groß ist die Datei, die ich geöffnet habe". Wird die Datei zwischendurch ersetzt, sind das zwei verschiedene Dateien.

Die Signatur im Original

Die Beschreibung im Original macht den Unterschied zu den verwandten Funktionen an einer einzigen Stelle fest:

fstat(resource $stream): array|false


/* stream - an open file pointer, as returned by fopen()
return - returns an array with statistics about the file,
or false on error

The function gathers the statistics of the file opened by the given
file pointer. Access, modification and inode change times are part
of the result. Unlike stat() it never resolves a filesystem path,
so a file that was renamed or replaced is still reported correctly. */

Der letzte Satz ist der Grund, warum diese Funktion überhaupt existiert, und er wird im Abschnitt zum Dateitausch praktisch vorgeführt.

Das Rückgabearray im Einzelnen

Die dreizehn Felder stammen unverändert aus dem Systemaufruf, den PHP darunter benutzt. Nicht alle sind auf jedem System aussagekräftig.

Feld Bedeutung Verlässlichkeit
size Größe in Bytes überall
mtime letzte Änderung des Inhalts überall
ctime letzte Änderung der Metadaten, etwa der Rechte Unix
atime letzter Zugriff oft abgeschaltet
ino Inode-Nummer, identifiziert die Datei selbst Unix
mode Typ und Rechte als Zahl Unix
uid, gid Eigentümer und Gruppe unter Windows immer 0
nlink, dev, rdev Anzahl der Verweise, Gerätenummern Unix
blksize, blocks Blockgröße und belegte Blöcke Unix

Eine Ausgabe mit print_r() zeigt allerdings 26 Einträge und wirkt zunächst fehlerhaft. Der Grund ist harmlos: PHP liefert jeden Wert zweimal, einmal numerisch indiziert in der Reihenfolge des Systemaufrufs und einmal unter seinem Namen. Für eigenen Code werden ausschließlich die benannten Schlüssel benutzt, die numerischen sind ein Erbe aus C und sagen niemandem etwas.

mtime, atime und ctime richtig lesen

Die drei Zeitstempel werden regelmäßig verwechselt, und eine Verwechslung ist besonders häufig: ctime ist nicht die Erstellungszeit. Das c steht für change und meint die letzte Änderung der Metadaten, also etwa der Zugriffsrechte oder des Eigentümers. Eine Erstellungszeit kennt PHP unter Unix gar nicht.

<?php

$handle = fopen('/tmp/bericht.csv', 'rb');
$d = fstat($handle);

printf("Inhalt geaendert: %s\n", date('d.m.Y H:i:s', $d['mtime']));
printf("Metadaten geaendert:%s\n", date('d.m.Y H:i:s', $d['ctime']));
printf("Zuletzt gelesen: %s\n", date('d.m.Y H:i:s', $d['atime']));

fclose($handle);

Wer eine Sortierung nach Alter baut, nimmt mtime. atime ist auf vielen Servern unbrauchbar, weil die Aktualisierung aus Leistungsgründen abgeschaltet ist.

fstat(), stat() und lstat() im Vergleich

Drei Funktionen mit ähnlichem Namen beantworten drei verschiedene Fragen. Der Unterschied zeigt sich am deutlichsten bei symbolischen Verweisen.

Funktion Eingabe Bei Symlink Nutzt den Cache
filesize() Pfad folgt dem Verweis ja
stat() Pfad folgt dem Verweis ja
lstat() Pfad beschreibt den Verweis selbst ja
fstat() offenes Handle nicht anwendbar nein

Die letzte Spalte ist der praktische Kern. PHP fstat() fragt bei jedem Aufruf das Betriebssystem, während die pfadbasierten Funktionen aus einem Zwischenspeicher antworten können.

Der Stat-Cache und warum filesize() manchmal lügt

PHP merkt sich Dateiinformationen innerhalb einer Anfrage. Wird eine Datei geschrieben und direkt danach mit filesize() gemessen, kann der alte Wert zurückkommen. Das fällt bei kurzen Skripten selten auf und bei langen Verarbeitungsläufen umso härter.

<?php

$pfad = '/tmp/wachsend.log';
file_put_contents($pfad, str_repeat('x', 100));

echo filesize($pfad); // 100

file_put_contents($pfad, str_repeat('x', 500));
echo filesize($pfad); /* evtl. immer noch 100 */

clearstatcache(true, $pfad);
echo filesize($pfad); // 500

/* am offenen Handle gibt es das Problem nicht */
$h = fopen($pfad, 'rb');
echo fstat($h)['size']; // 500
fclose($h);

Der zweite Parameter von clearstatcache() begrenzt das Leeren auf einen Pfad und ist die schonendere Variante. Wer ohnehin ein Handle offen hat, spart sich die ganze Überlegung, denn PHP fstat() liest immer den aktuellen Zustand.

Erkennen, ob die Datei ersetzt wurde

Zwei Prozesse arbeiten auf demselben Pfad, und dazwischen wird umbenannt. Der eine schreibt dann in eine Datei, die unter dem Namen längst nicht mehr erreichbar ist. Sichtbar wird das über die Inode-Nummer: Sie gehört zur Datei, nicht zum Namen.

<?php

$pfad = '/var/log/anwendung.log';
$h = fopen($pfad, 'rb');

$offen = fstat($h)['ino'];
$aktuell = stat($pfad)['ino'];

if ($offen !== $aktuell) {
/* die Datei wurde rotiert, Handle neu oeffnen */
fclose($h);
$h = fopen($pfad, 'rb');
}

Genau dieser Vergleich ist der Grund, warum es PHP fstat() überhaupt gibt. Mit pfadbasierten Funktionen allein lässt sich die Frage nicht beantworten.

Welche der vier Funktionen im konkreten Fall die richtige ist, zeigt die folgende Entscheidung.

flowchart TD
  A[Was liegt vor] --> B{Offenes Handle}
  B -->|ja| C[fstat]
  B -->|nein| D{Symlink selbst gemeint}
  D -->|ja| E[lstat]
  D -->|nein| F{Nur Groesse noetig}
  F -->|ja| G[filesize]
  F -->|nein| H[stat]

Sobald ein Handle im Spiel ist, gibt es keinen Grund mehr, über den Pfad zu gehen.

Praxis: Content-Length beim Ausliefern setzen

Beim Ausliefern geschützter Dateien muss die Längenangabe im Header zum tatsächlich gesendeten Inhalt passen. Stimmt sie nicht, bricht der Download beim Empfänger ab oder hängt. Der sichere Weg nimmt beide Angaben aus derselben Quelle.

<?php

$pfad = '/var/www/geschuetzt/handbuch.pdf';
$h = fopen($pfad, 'rb');

if ($h === false) {
http_response_code(404);
exit;
}

$groesse = fstat($h)['size'];

header('Content-Type: application/pdf');
header('Content-Length: ' . $groesse);
header('Content-Disposition: attachment; filename="handbuch.pdf"');

fpassthru($h);
fclose($h);

Die Reihenfolge ist zwingend: erst öffnen, dann messen, dann Header setzen, dann ausgeben. Nach der ersten Ausgabe lässt sich kein Header mehr senden. Wer eine Datei ohne eigene Schleife ausliefert, findet die Alternativen im Tutorial zu PHP readfile() und dem direkten Ausliefern von Dateien.

Praxis: eine wachsende Logdatei beobachten

Ein Auswertungsskript soll neue Zeilen verarbeiten, sobald sie geschrieben werden. Das Handle bleibt offen, und PHP fstat() liefert bei jedem Durchlauf die aktuelle Größe.

<?php

$h = fopen('/var/log/anwendung.log', 'rb');
$letzte = fstat($h)['size'];
fseek($h, $letzte);

for ($i = 0; $i < 60; $i++) {
$jetzt = fstat($h)['size'];

if ($jetzt > $letzte) {
while (($zeile = fgets($h)) !== false) {
echo 'neu: ' . $zeile;
}
$letzte = $jetzt;
}
sleep(1);
}
fclose($h);

Ohne offenes Handle wäre dafür in jedem Durchlauf ein neues Öffnen nötig, dazu ein Leeren des Zwischenspeichers. Woher das Handle kommt und welche Modi es gibt, klärt das Tutorial zu PHP fopen() und dem Öffnen, Lesen und Schreiben von Dateien.

Grenzen: Ströme ohne Dateisystem und Windows

Nicht jedes Handle gehört zu einer echten Datei. Bei php://memory und php://temp füllt PHP fstat() nur einen Teil der Felder sinnvoll; ino, dev und die Zeitstempel stehen dann auf 0. Verlässlich ist dort im Wesentlichen size.

Unter Windows sind uid, gid, ino und blocks ohne Aussage und immer 0. Wer darauf eine Rechteprüfung oder eine Identitätsprüfung baut, baut auf Nullen. Zum Prüfen von Zugriffsrechten sind stattdessen is_readable() und die verwandten Funktionen zuständig, die auf beiden Plattformen funktionieren.

Fazit

PHP fstat() beantwortet die Frage nach Größe, Zeitstempeln und Identität einer Datei, die gerade offen ist. Damit umgeht es zwei Fallen auf einmal: den Stat-Cache und das Zeitfenster zwischen Prüfung und Zugriff.

Drei Punkte bleiben hängen. Benutzt werden ausschließlich die benannten Schlüssel, ctime ist keine Erstellungszeit, und die Inode-Nummer verrät, ob unter dem Pfad noch dieselbe Datei liegt. Für alles, was nur einen Pfad hat, bleiben stat() und filesize() die richtige Wahl.

 

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.