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:
[php]
function filedata($path) {
// Vaciamos la caché de lectura de disco
clearstatcache();
// Comprobamos si el fichero existe
$data[«exists»] = is_file($path);
// Comprobamos si el fichero es escribible
$data[«writable»] = is_writable($path);
// Leemos los permisos del fichero
$data[«chmod»] = ($data[«exists»] ? substr(sprintf(«%o», fileperms($path)), -4) : FALSE);
// Extraemos la extensión, un sólo paso
$data[«ext»] = substr(strrchr($path, «.»),1);
// Primer paso de lectura de ruta
$data[«path»] = array_shift(explode(«.».$data[«ext»],$path));
// Primer paso de lectura de nombre
$data[«name»] = array_pop(explode(«/»,$data[«path»]));
// 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;
}
[/php]
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
)
2 comentarios en “Función PHP – Extraer ruta, nombre y extensión de un archivo”