Función PHP – Extraer ruta, nombre y extensión de un archivo
La curiosidad me la ha despertado el viciño r0sk en su blog a partir de las diferentes opciones que él y sus compañeros de trabajo (saludos a todos de mis partes!) han desarrollado para extraer información de una ruta, nombre y extensión de un archivo dado. Asi que a ellos, a él y a su señora les dedico este post/opinión.
Planteamiento
Algo que en principio parece tan trivial, se complica si empezamos a pensar en las diferentes posibilidades de uso (o mal uso) de una función de este tipo:
- Extensión sin nombre: .htaccess
- Nombre sin extensión: name
- Nombre simplón: name.jpeg
- Nombre complejo: name.surname.gif
- Ruta absoluta: /path/to/name.surname.tar.gz
- Ruta relativa: ../../path/to/name.surname.tar.gz
- BONUS: Cadena vacia para romper la función Comillas vacias ''
- BONUS 2: Cadena malformada para romper la función '/\/.path///file/.gif'
- BONUS 3: Ruta sin archivo '/path/to/folder/'
Requerimientos
Si además queremos aumentar los requerimientos, la cosa se puede complicar bastante:
- Yo como soy un perfeccionista de mierda, quiero 7 Campos:
- ¿ El fichero existe ? Puede ser útil en caso de querer borrar/comprobar
- ¿ El fichero es escribible ? Puede ser útil en caso de querer borrar/editar
- Los permisos del archivo en formato "humano"
- El Nombre sin extensión
- La Extensión sin nombre
- El Archivo (nombre+extensión)
- La Ruta
- La función debe ser totalmente compatible hacia atrás, al menos cubriendo a PHP4
- En la medida de lo posible, no quiero errores si el usuario me pasa datos no válidos
- No quiero cadenas vacias, si uno de los campos no existe quiero un lindo FALSE
- Quiero la ruta sin / al final, añadirla en otras partes del flujo de código es mucho más sencillo que tener que quitarla a posteriori.
Con las manos en la masa
Asi que tras un poco de trapicheo y consulta, he acabado con este engendro, que podría ser mucho más corto, pero cumple todos los requerimientos anteriores:
-
function filedata($path) {
-
// Vaciamos la caché de lectura de disco
-
// Comprobamos si el fichero existe
-
// Comprobamos si el fichero es escribible
-
// Leemos los permisos del fichero
-
// Extraemos la extensión, un sólo paso
-
// Primer paso de lectura de ruta
-
// Primer paso de lectura de nombre
-
// Ajustamos nombre a FALSE si está vacio
-
$data["name"] = ($data["name"] ? $data["name"] : FALSE);
-
// Ajustamos la ruta a FALSE si está vacia
-
$data["path"] = ($data["exists"] ? ($data["name"] ? realpath(array_shift(explode($data["name"],$data["path"]))) : realpath(array_shift(explode($data["ext"],$data["path"])))) : ($data["name"] ? array_shift(explode($data["name"],$data["path"])) : ($data["ext"] ? array_shift(explode($data["ext"],$data["path"])) : rtrim($data["path"],"/")))) ;
-
// Ajustamos el nombre a FALSE si está vacio o a su valor en caso contrario
-
$data["filename"] = (($data["name"] OR $data["ext"]) ? $data["name"].($data["ext"] ? "." : "").$data["ext"] : FALSE);
-
// Devolvemos los resultados
-
return $data;
-
}
Resultado y demostración
Puedes ver una demostración del uso de esta función en vivo y en directo en la dirección http://www.propiedadprivada.com/lab/phproute/
O bien comprobar el resultado aqui mismo:
Extensión sin nombre: .htaccess
Array (7)
(
| ['exists'] = Boolean(1) TRUE
| ['writable'] = Boolean(0) FALSE
| ['chmod'] = String(4) " 0644 "
| ['ext'] = String(8) " htaccess "
| ['path'] = Boolean(0) FALSE
| ['name'] = Boolean(0) FALSE
| ['filename'] = String(9) " .htaccess "
)
Nombre sin extensión: name
Array (7)
(
| ['exists'] = Boolean(1) TRUE
| ['writable'] = Boolean(0) FALSE
| ['chmod'] = String(4) " 0644 "
| ['ext'] = Boolean(0) FALSE
| ['path'] = Boolean(0) FALSE
| ['name'] = String(4) " name "
| ['filename'] = String(4) " name "
)
Nombre simplón: name.jpeg
Array (7)
(
| ['exists'] = Boolean(1) TRUE
| ['writable'] = Boolean(0) FALSE
| ['chmod'] = String(4) " 0644 "
| ['ext'] = String(4) " jpeg "
| ['path'] = Boolean(0) FALSE
| ['name'] = String(4) " name "
| ['filename'] = String(9) " name.jpeg "
)
Nombre complejo: name.surname.gif
Array (7)
(
| ['exists'] = Boolean(1) TRUE
| ['writable'] = Boolean(0) FALSE
| ['chmod'] = String(4) " 0644 "
| ['ext'] = String(3) " gif "
| ['path'] = Boolean(0) FALSE
| ['name'] = String(12) " name.surname "
| ['filename'] = String(16) " name.surname.gif "
)
Ruta absoluta:
/home/httpd/vhosts/propiedadprivada.com/httpdocs/lab/phproute/name.surname.tar.gz
Array (7)
(
| ['exists'] = Boolean(1) TRUE
| ['writable'] = Boolean(0) FALSE
| ['chmod'] = String(4) " 0644 "
| ['ext'] = String(2) " gz "
| ['path'] = String(61) " /home/httpd/vhosts/propiedadprivada.com/httpdocs/lab/phproute "
| ['name'] = String(16) " name.surname.tar "
| ['filename'] = String(19) " name.surname.tar.gz "
)
Ruta absoluta que no existe: /path/to/myname.jpeg
Array (7)
(
| ['exists'] = Boolean(0) FALSE
| ['writable'] = Boolean(0) FALSE
| ['chmod'] = Boolean(0) FALSE
| ['ext'] = String(4) " jpeg "
| ['path'] = String(9) " /path/to/ "
| ['name'] = String(6) " myname "
| ['filename'] = String(11) " myname.jpeg "
)
Ruta relativa: ../../lab/phproute/name.surname.tar.gz
Array (7)
(
| ['exists'] = Boolean(1) TRUE
| ['writable'] = Boolean(0) FALSE
| ['chmod'] = String(4) " 0644 "
| ['ext'] = String(2) " gz "
| ['path'] = String(61) " /home/httpd/vhosts/propiedadprivada.com/httpdocs/lab/phproute "
| ['name'] = String(16) " name.surname.tar "
| ['filename'] = String(19) " name.surname.tar.gz "
)
BONUS: Cadena vacia para romper la función ''
Array (7)
(
| ['exists'] = Boolean(0) FALSE
| ['writable'] = Boolean(0) FALSE
| ['chmod'] = Boolean(0) FALSE
| ['ext'] = Boolean(0) FALSE
| ['path'] = String(0) " "
| ['name'] = Boolean(0) FALSE
| ['filename'] = Boolean(0) FALSE
)
BONUS 2: Cadena malformada para romper la función '/\/.path///file/.gif'
Array (7)
(
| ['exists'] = Boolean(0) FALSE
| ['writable'] = Boolean(0) FALSE
| ['chmod'] = Boolean(0) FALSE
| ['ext'] = String(3) " gif "
| ['path'] = String(16) " /\/.path///file/ "
| ['name'] = Boolean(0) FALSE
| ['filename'] = String(4) " .gif "
)
BONUS 3: Ruta sin archivo '/path/to/folder/'
Array (7)
(
| ['exists'] = Boolean(0) FALSE
| ['writable'] = Boolean(0) FALSE
| ['chmod'] = Boolean(0) FALSE
| ['ext'] = Boolean(0) FALSE
| ['path'] = String(16) " /path/to/folder "
| ['name'] = Boolean(0) FALSE
| ['filename'] = Boolean(0) FALSE
)