W3docs

fileperms()

La funzione fileperms() di PHP restituisce i permessi di un file come intero contenente sia il tipo di file che i bit di accesso.

La funzione fileperms() di PHP legge i bit di permesso e di tipo di un file dal filesystem e li restituisce come un unico intero (la modalità di file Unix). Questa pagina spiega cosa contiene effettivamente quell'intero, come convertirlo nella familiare forma ottale come 0644, l'insidia che coglie di sorpresa quasi tutti la prima volta, e come trasformarlo in una stringa in stile ls -l. Sui sistemi non Unix come Windows il valore è meno significativo, ma la funzione funziona comunque.

Cos'è la funzione fileperms()?

La funzione fileperms() restituisce i permessi del file indicato da filename come intero, oppure false in caso di errore (ad esempio, se il file non esiste). L'intero codifica sia il tipo di file (file normale, directory, collegamento simbolico, ecc.) che i bit di accesso (lettura/scrittura/esecuzione per proprietario, gruppo e altri).

Sintassi

fileperms(string $filename): int|false
  • $filename — percorso del file o della directory da esaminare.

Poiché il risultato è un intero grezzo, nella quasi totalità dei casi si converte in ottale con sprintf() prima di mostrarlo a un utente:

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

L'insidia: il valore non è semplicemente 0644

La sorpresa numero uno è che fileperms() non restituisce 0644. Restituisce la modalità completa, che include i bit di tipo file. Un file normale con permessi 0644 riporta la modalità ottale 100644, e una directory con 0755 riporta 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)

Per ottenere solo i bit di permesso, si applica la maschera & 0777 al valore (che elimina tutto ciò che si trova al di sopra delle tre cifre ottali inferiori), oppure si prendono le ultime cifre della stringa ottale con substr(). Si usa il mascheramento quando si vuole confrontare con un numero; si usa substr() quando si vuole una stringa stampabile con quattro cifre.

Lettura dei permessi di un file esistente

Nel codice reale, verificare prima l'esistenza del file per evitare di generare un avviso quando è assente:

<?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";
}

Vedere file_exists() per verificare l'esistenza e is_readable() quando interessa sapere se il proprio processo può effettivamente leggere il file, piuttosto che la modalità grezza.

Trasformare la modalità in una stringa ls -l

I bit restituiti da fileperms() corrispondono direttamente alla notazione -rw-r--r-- stampata da ls -l. I bit alti selezionano il carattere di tipo; i nove bit bassi sono le triplette rwx per proprietario, gruppo e altri. Questo frammento (adattato dal manuale PHP ufficiale) costruisce quella stringa:

<?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--

Quando usarla?

  • Controllo — registrare o riportare i permessi di directory di upload, file di configurazione o cartelle cache.
  • Diagnostica — verificare che uno script di distribuzione abbia impostato correttamente 0755/0644 invece di indovinare.
  • Correzioni condizionali — leggere la modalità corrente e, se è troppo permissiva, restringerla con chmod().

Insidie e suggerimenti

  • Applicare sempre la maschera & 0777 (o suddividere la stringa) prima di confrontare con un letterale come 0644 — altrimenti i bit di tipo fanno fallire ogni confronto.
  • I risultati sono nella cache. PHP memorizza nella cache i dati stat, quindi se si modificano i permessi e li si rilegge nella stessa richiesta, chiamare prima clearstatcache().
  • Restituisce false in caso di errore, non 0. I permessi pari a 0 sono tecnicamente validi, quindi usare === se occorre distinguere una modalità 0 reale da un errore.
  • Windows è limitato. I bit di esecuzione e di gruppo/altri non hanno significato su Windows, quindi il valore riflette solo ciò che quella piattaforma espone.
  • Per l'insieme completo dei metadati di un file (dimensione, proprietario, timestamp) in un'unica chiamata, usare stat(); filetype() restituisce solo il tipo come parola, ad esempio file o dir.

Conclusione

fileperms() restituisce la modalità di file Unix completa come intero, combinando il tipo di file con i bit di accesso. Convertirla in ottale con sprintf('%o', ...), ricordare di applicare la maschera & 0777 (o prendere le ultime cifre) per isolare i bit di permesso, e abbinarla a chmod() quando occorre modificare quei permessi invece di leggerli soltanto.

Esercizio

Pratica
Quali delle seguenti affermazioni sui permessi dei file PHP sono vere?
Quali delle seguenti affermazioni sui permessi dei file PHP sono vere?
Was this page helpful?