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/0644correctamente 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 como0644; 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
falseen caso de error, no0. Los permisos de0son técnicamente válidos, así que usa===si necesitas distinguir un modo real de0de 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 comofileodir.
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.