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/0644korrekt 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
& 0777maskieren (oder den String slicen), bevor man mit einem Literal wie0644vergleicht — 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
falsebei einem Fehler zurück, nicht0. Berechtigungen von0sind technisch gültig. Teste daher mit===, wenn du zwischen einem echten0-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 wiefileoderdirzurü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.