W3docs

fileperms()

La función fileperms() de PHP devuelve los permisos de un archivo como entero. Aprende a convertirlo a formato octal y a interpretar los bits de tipo.

La función fileperms() de PHP lee los bits de permisos y tipo de un archivo desde el sistema de archivos y los devuelve como un único entero (el modo de archivo Unix). Esta página explica qué contiene realmente ese entero, cómo convertirlo a la forma octal habitual como 0644, el error que sorprende a casi todo el mundo la primera vez, y cómo transformarlo en una cadena estilo ls -l. En sistemas no Unix como Windows el valor tiene menos significado, pero la función sigue funcionando.

¿Qué es la función fileperms()?

La función fileperms() devuelve los permisos del archivo indicado por filename como un entero, o false en caso de error (por ejemplo, si el archivo no existe). El entero codifica tanto el tipo de archivo (archivo regular, directorio, enlace simbólico, etc.) como los bits de acceso (lectura/escritura/ejecución para el propietario, el grupo y otros).

Sintaxis

fileperms(string $filename): int|false
  • $filename — ruta al archivo o directorio que se desea inspeccionar.

Como el resultado es un entero sin procesar, casi siempre se convierte a octal con sprintf() antes de mostrárselo a un usuario:

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

El error más común: el valor no es simplemente 0644

La mayor sorpresa es que fileperms() no devuelve 0644. Devuelve el modo completo, que incluye los bits de tipo de archivo. Un archivo regular con permisos 0644 reporta el modo octal 100644, y un directorio con 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 obtener solo los bits de permisos, aplica una máscara con & 0777 (que elimina todo lo que está por encima de los tres dígitos octales inferiores), o toma los últimos dígitos de la cadena octal con substr(). Usa la máscara cuando quieras comparar contra un número; usa substr() cuando quieras una cadena imprimible con cuatro dígitos.

Leer los permisos de un archivo existente

En código real, comprueba primero que el archivo existe para no generar una advertencia cuando no se encuentra:

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

Consulta file_exists() para verificar la existencia e is_readable() cuando lo que te importa es si tu proceso puede realmente leer el archivo en lugar del modo sin procesar.

Convertir el modo en una cadena estilo ls -l

Los bits devueltos por fileperms() se corresponden directamente con la notación -rw-r--r-- que imprime ls -l. Los bits altos seleccionan el carácter de tipo; los nueve bits bajos son los tripletes rwx para propietario, grupo y otros. Este fragmento (adaptado del manual oficial de PHP) construye esa cadena:

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

¿Cuándo usarla?

  • Auditoría — registra o informa los permisos de directorios de subida, archivos de configuración o carpetas de caché.
  • Diagnóstico — confirma que un script de despliegue estableció 0755/0644 correctamente en lugar de adivinarlo.
  • Correcciones condicionales — lee el modo actual y, si es demasiado permisivo, ajústalo con chmod().

Errores y consejos

  • Aplica siempre la máscara & 0777 (o recorta la cadena) antes de comparar con un literal como 0644; de lo contrario, los bits de tipo harán que toda comparación falle.
  • Los resultados se almacenan en caché. PHP guarda en caché los datos de stat, por lo que si cambias los permisos y los vuelves a leer en la misma solicitud, llama primero a clearstatcache().
  • Devuelve false en caso de error, no 0. Los permisos de 0 son técnicamente válidos, así que usa === si necesitas distinguir un modo real de 0 de un fallo.
  • Windows es limitado. Los bits de ejecución y de grupo/otros no son significativos en Windows, por lo que el valor refleja solo lo que expone esa plataforma.
  • Para el conjunto completo de metadatos del archivo (tamaño, propietario, marcas de tiempo) en una sola llamada, usa stat(); filetype() devuelve solo el tipo como una palabra como file o dir.

Conclusión

fileperms() devuelve el modo completo de archivo Unix como un entero, combinando el tipo de archivo con los bits de acceso. Conviértelo a octal con sprintf('%o', ...), recuerda aplicar la máscara & 0777 (o tomar los últimos dígitos) para aislar los bits de permisos, y combínalo con chmod() cuando necesites cambiar esos permisos en lugar de solo leerlos.

Práctica

Práctica
¿Cuáles de las siguientes afirmaciones sobre los permisos de archivos de PHP son verdaderas?
¿Cuáles de las siguientes afirmaciones sobre los permisos de archivos de PHP son verdaderas?
Was this page helpful?