MarcosBL

Aprendiz de todo, maestro de nada

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:

[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

Comments are closed.