W3docs

fileperms()

A função fileperms() do PHP retorna as permissões de um arquivo como um inteiro que inclui os bits de tipo e de acesso.

A função fileperms() do PHP lê os bits de permissão e tipo de um arquivo a partir do sistema de ficheiros e devolve-os como um único inteiro (o file mode Unix). Esta página explica o que esse inteiro contém, como convertê-lo para a forma octal familiar como 0644, a armadilha que surpreende quase toda a gente na primeira vez, e como transformá-lo numa string no estilo ls -l. Em sistemas não-Unix como o Windows, o valor tem menos significado, mas a função continua a funcionar.

O que é a Função fileperms()?

A função fileperms() devolve as permissões do arquivo indicado por filename como um inteiro, ou false em caso de falha (por exemplo, se o arquivo não existir). O inteiro codifica tanto o tipo de arquivo (arquivo regular, diretório, link simbólico, etc.) como os bits de acesso (leitura/escrita/execução para o proprietário, grupo e outros).

Sintaxe

fileperms(string $filename): int|false
  • $filename — caminho para o arquivo ou diretório a inspecionar.

Como o resultado é um inteiro bruto, quase sempre o converte para octal com sprintf() antes de o mostrar:

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

A armadilha: o valor não é apenas 0644

A maior surpresa é que fileperms() não devolve 0644. Devolve o modo completo, que inclui os bits de tipo de arquivo. Um arquivo regular com permissões 0644 reporta o modo octal 100644, e um diretório com 0755 reporta 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)

Para obter apenas os bits de permissão, aplique a máscara com & 0777 (que descarta tudo acima dos três dígitos octais inferiores), ou extraia os últimos dígitos da string octal com substr(). Use a máscara quando quiser comparar com um número; use substr() quando quiser uma string imprimível com quatro dígitos.

Lendo as permissões de um arquivo existente

No código real, verifique primeiro se o arquivo existe para não disparar um aviso quando ele estiver ausente:

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

Veja file_exists() para verificar a existência e is_readable() quando quiser saber se o seu processo consegue realmente ler o arquivo, em vez do modo bruto.

Convertendo o modo numa string ls -l

Os bits devolvidos por fileperms() mapeiam diretamente para a notação -rw-r--r-- impressa pelo ls -l. Os bits mais altos selecionam o caractere de tipo; os nove bits mais baixos são os triplets rwx para proprietário, grupo e outros. Este trecho (adaptado do manual oficial do PHP) constrói essa string:

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

  • Auditoria — registar ou reportar as permissões de diretórios de upload, arquivos de configuração ou pastas de cache.
  • Diagnóstico — confirmar se um script de implantação definiu 0755/0644 corretamente em vez de adivinhar.
  • Correções condicionais — ler o modo atual e, se for demasiado permissivo, restringi-lo com chmod().

Armadilhas e dicas

  • Sempre aplique a máscara com & 0777 (ou fatie a string) antes de comparar com um literal como 0644 — caso contrário, os bits de tipo fazem com que cada comparação falhe.
  • Os resultados são guardados em cache. O PHP guarda os dados stat em cache, portanto, se alterar as permissões e as reler no mesmo pedido, chame clearstatcache() primeiro.
  • Devolve false em caso de erro, não 0. As permissões 0 são tecnicamente válidas, por isso use === se precisar distinguir um modo real 0 de uma falha.
  • O Windows tem limitações. Os bits de execução e de grupo/outros não têm significado no Windows, pelo que o valor reflete apenas o que essa plataforma expõe.
  • Para obter todos os metadados do arquivo (tamanho, proprietário, timestamps) numa só chamada, use stat(); filetype() devolve apenas o tipo como uma palavra como file ou dir.

Conclusão

fileperms() devolve o modo Unix completo do arquivo como um inteiro, combinando o tipo de arquivo com os bits de acesso. Converta-o para octal com sprintf('%o', ...), lembre-se de aplicar a máscara com & 0777 (ou extrair os últimos dígitos) para isolar os bits de permissão, e use-o em conjunto com chmod() quando precisar de alterar essas permissões em vez de apenas as ler.

Prática

Prática
Quais das afirmações a seguir sobre permissões de arquivos em PHP são verdadeiras?
Quais das afirmações a seguir sobre permissões de arquivos em PHP são verdadeiras?
Was this page helpful?