W3docs

fileperms()

Die PHP-Funktion fileperms() gibt die Berechtigungen einer Datei als Integer zurück. Diese Seite erklärt, wie man den Wert korrekt auswertet.

PHPs fileperms()-Funktion liest die Berechtigungs- und Typbits einer Datei aus dem Dateisystem und gibt sie als einzelnen Integer (den Unix-Dateimodus) zurück. Diese Seite erklärt, was dieser Integer tatsächlich enthält, wie man ihn in die vertraute Oktalform wie 0644 umrechnet, die Falle, in die fast alle beim ersten Mal tappen, und wie man ihn in einen ls -l-ähnlichen String umwandelt. Auf Nicht-Unix-Systemen wie Windows ist der Wert weniger aussagekräftig, aber die Funktion funktioniert trotzdem.

Was ist die fileperms()-Funktion?

Die fileperms()-Funktion gibt die Berechtigungen der durch filename angegebenen Datei als Integer zurück, oder false bei einem Fehler (zum Beispiel, wenn die Datei nicht existiert). Der Integer kodiert sowohl den Dateityp (reguläre Datei, Verzeichnis, symbolischer Link usw.) als auch die Zugriffsbits (Lesen/Schreiben/Ausführen für Eigentümer, Gruppe und andere).

Syntax

fileperms(string $filename): int|false
  • $filename — Pfad zur zu prüfenden Datei oder zum Verzeichnis.

Da das Ergebnis ein roher Integer ist, konvertiert man ihn fast immer mit sprintf() in Oktal, bevor man ihn einem Menschen anzeigt:

sprintf('%o', fileperms($filename));

Die Falle: Der Wert ist nicht einfach 0644

Die größte Überraschung ist, dass fileperms() nicht 0644 zurückgibt. Es gibt den vollständigen Modus zurück, der auch die Dateityp-Bits enthält. Eine reguläre Datei mit 0644-Berechtigungen meldet den Oktalmodus 100644, und ein Verzeichnis mit 0755 meldet 40755:

<?php

$filename = 'demo.txt';
file_put_contents($filename, 'demo');
chmod($filename, 0644);

$perms = fileperms($filename);

echo $perms, "\n";                       // 33188  (decimal)
echo sprintf('%o', $perms), "\n";        // 100644 (octal, includes type bits)
echo sprintf('%o', $perms & 0777), "\n"; // 644    (permission bits only)
echo substr(sprintf('%o', $perms), -4);  // 0644   (last four octal digits)

Um nur die Berechtigungs-Bits zu erhalten, maskiert man den Wert mit & 0777 (was alles oberhalb der untersten drei Oktalstellen entfernt), oder man nimmt die letzten Stellen des Oktal-Strings mit substr(). Verwende den Maskierungsansatz, wenn du mit einer Zahl vergleichen möchtest; verwende substr(), wenn du einen auf vier Stellen aufgefüllten druckbaren String möchtest.

Berechtigungen einer vorhandenen Datei auslesen

Im echten Code sollte man zuerst prüfen, ob die Datei existiert, um keine Warnung auszulösen, wenn sie fehlt:

<?php

$filename = 'demo.txt';
file_put_contents($filename, 'demo');
chmod($filename, 0644);

if (file_exists($filename)) {
    $perms = fileperms($filename);
    printf("%s -> %s\n", $filename, substr(sprintf('%o', $perms), -4));
    // demo.txt -> 0644
} else {
    echo "File not found.\n";
}

Siehe file_exists() zum Prüfen der Existenz und is_readable(), wenn es darauf ankommt, ob dein Prozess die Datei tatsächlich lesen kann, anstatt den rohen Modus zu prüfen.

Den Modus in einen ls -l-String umwandeln

Die von fileperms() zurückgegebenen Bits entsprechen direkt der -rw-r--r---Notation, die ls -l ausgibt. Die hohen Bits bestimmen das Typzeichen; die unteren neun Bits sind die rwx-Triplets für Eigentümer, Gruppe und andere. Dieses Snippet (angelehnt an das offizielle PHP-Handbuch) baut diesen String auf:

<?php

$filename = 'demo.txt';
file_put_contents($filename, 'demo');
chmod($filename, 0644);

$perms = fileperms($filename);

switch ($perms & 0xF000) {
    case 0xC000: $info = 's'; break; // socket
    case 0xA000: $info = 'l'; break; // symbolic link
    case 0x8000: $info = '-'; break; // regular file
    case 0x6000: $info = 'b'; break; // block special
    case 0x4000: $info = 'd'; break; // directory
    case 0x2000: $info = 'c'; break; // character special
    case 0x1000: $info = 'p'; break; // FIFO pipe
    default:     $info = 'u';        // unknown
}

// Owner
$info .= ($perms & 0x0100) ? 'r' : '-';
$info .= ($perms & 0x0080) ? 'w' : '-';
$info .= ($perms & 0x0040)
    ? (($perms & 0x0800) ? 's' : 'x')
    : (($perms & 0x0800) ? 'S' : '-');
// Group
$info .= ($perms & 0x0020) ? 'r' : '-';
$info .= ($perms & 0x0010) ? 'w' : '-';
$info .= ($perms & 0x0008)
    ? (($perms & 0x0400) ? 's' : 'x')
    : (($perms & 0x0400) ? 'S' : '-');
// Other
$info .= ($perms & 0x0004) ? 'r' : '-';
$info .= ($perms & 0x0002) ? 'w' : '-';
$info .= ($perms & 0x0001)
    ? (($perms & 0x0200) ? 't' : 'x')
    : (($perms & 0x0200) ? 'T' : '-');

echo $info; // -rw-r--r--

Wann würde ich das verwenden?

  • Auditing — Protokolliere oder melde die Berechtigungen von Upload-Verzeichnissen, Konfigurationsdateien oder Cache-Ordnern.
  • Diagnose — Stelle sicher, dass ein Deployment-Skript 0755/0644 korrekt gesetzt hat, anstatt zu raten.
  • Bedingte Korrekturen — Lese den aktuellen Modus aus, und wenn er zu freizügig ist, schränke ihn mit chmod() ein.

Fallstricke und Tipps

  • Immer mit & 0777 maskieren (oder den String slicen), bevor man mit einem Literal wie 0644 vergleicht — andernfalls lassen die Typbits jeden Vergleich fehlschlagen.
  • Ergebnisse werden gecacht. PHP cached Stat-Daten. Wenn du also Berechtigungen änderst und sie innerhalb derselben Anfrage erneut liest, rufe zuerst clearstatcache() auf.
  • Gibt false bei einem Fehler zurück, nicht 0. Berechtigungen von 0 sind technisch gültig. Teste daher mit ===, wenn du zwischen einem echten 0-Modus und einem Fehler unterscheiden musst.
  • Windows ist eingeschränkt. Die Ausführungs- und Gruppen-/Andere-Bits sind unter Windows nicht aussagekräftig, daher gibt der Wert nur das wieder, was diese Plattform bereitstellt.
  • Für den vollständigen Satz an Datei-Metadaten (Größe, Eigentümer, Zeitstempel) in einem einzigen Aufruf verwende stat(); filetype() gibt nur den Typ als Wort wie file oder dir zurück.

Fazit

fileperms() gibt den vollständigen Unix-Dateimodus als Integer zurück und kombiniert dabei den Dateityp mit den Zugriffsbits. Konvertiere ihn mit sprintf('%o', ...) in Oktal, denke daran, mit & 0777 zu maskieren (oder die letzten Stellen zu nehmen), um die Berechtigungs-Bits zu isolieren, und kombiniere es mit chmod(), wenn du diese Berechtigungen nicht nur lesen, sondern auch ändern möchtest.

Übungen

Übung
Welche der folgenden Aussagen über PHP-Dateiberechtigungen sind wahr?
Welche der folgenden Aussagen über PHP-Dateiberechtigungen sind wahr?
Was this page helpful?