¿Cómo obtengo una extensión de archivo en PHP?

723

Esta es una pregunta que puede leer en todas partes en la web con varias respuestas:

$ext = end(explode('.', $filename));
$ext = substr(strrchr($filename, '.'), 1);
$ext = substr($filename, strrpos($filename, '.') + 1);
$ext = preg_replace('/^.*\.([^.]+)$/D', '$1', $filename);

$exts = split("[/\\.]", $filename);
$n    = count($exts)-1;
$ext  = $exts[$n];

etc.

Sin embargo, siempre existe "la mejor manera" y debe estar en Stack Overflow.

e-satis
fuente
15
Fuente de preguntas y respuestas: cowburn.info/2008/01/13/get-file-extension-comparison
salathe
55
Una forma más de obtener ext esstrrchr($filename, '.');
verybadbug

Respuestas:

1776

Las personas de otros lenguajes de secuencias de comandos siempre piensan que la suya es mejor porque tienen una función incorporada para hacer eso y no PHP (estoy viendo Pythonistas en este momento :-)).

De hecho, existe, pero pocas personas lo saben. Cumplir pathinfo():

$ext = pathinfo($filename, PATHINFO_EXTENSION);

Esto es rápido e incorporado. pathinfo()puede darle otra información, como la ruta canónica, dependiendo de la constante que le pase.

Recuerde que si desea poder tratar con caracteres no ASCII, primero debe establecer la configuración regional. P.EJ:

setlocale(LC_ALL,'en_US.UTF-8');

Además, tenga en cuenta que esto no tiene en cuenta el contenido del archivo o el tipo mime, solo obtiene la extensión. Pero es lo que pediste.

Por último, tenga en cuenta que esto solo funciona para una ruta de archivo, no para una ruta de recursos URL, que se cubre con PARSE_URL.

Disfrutar

e-satis
fuente
62
Desearía poder votar esto dos veces. No puedo decirte cuánto código he podido reemplazar usando pathinfo
Mark Biek
8
Yo también. ¡Por eso lo puse aquí!
e-satis
77
Lo que sabes, resulta que hay una mejor manera.
Ben
19
@khizaransari Debes buscar otro proveedor de alojamiento, el que tienes es estúpido. Realmente, lo digo en serio. No hay ninguna razón para deshabilitar esta función. Diles eso. Como solución alternativa: function get_ext($fname){ return substr($fname, strrpos($fname, ".") + 1); }asegúrese de que el archivo tenga una extensión, ¡puede hacer cualquier cosa cuando pase una ruta como argumento!
Luc
12
mi idea de PHP en comparación con Python cambió por completo ahora que conozco esta función: O
Tommaso Barbugli
166

pathinfo()

$path_info = pathinfo('/foo/bar/baz.bill');

echo $path_info['extension']; // "bill"
Adam Wright
fuente
14
Desde PHP 5.5 ->echo pathinfo('/foo/bar/baz.bill')['extension'];
Salman A
1
Esto incluso funciona en este nivel (Twitter json): $ ext = pathinfo ($ result-> extended_entities-> media [0] -> video_info-> variantes [1] -> url, PATHINFO_EXTENSION);
KJS
101

URL de ejemplo: http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ

A) No use sugerencias insegurasPATHINFO :

pathinfo($url)['dirname']   🡺 'http://example.com/myfolder'
pathinfo($url)['basename']  🡺 'sympony.mp3?a=1&b=2#XYZ'         // <------- BAD !!
pathinfo($url)['extension'] 🡺 'mp3?a=1&b=2#XYZ'                 // <------- BAD !!
pathinfo($url)['filename']  🡺 'sympony'

B) Use PARSE_URL :

parse_url($url)['scheme']   🡺 'http'
parse_url($url)['host']     🡺 'example.com'
parse_url($url)['path']     🡺 '/myfolder/sympony.mp3'
parse_url($url)['query']    🡺 'aa=1&bb=2'
parse_url($url)['fragment'] 🡺 'XYZ'

BONIFICACIÓN: Vea todos los ejemplos nativos de PHP

T.Todua
fuente
3
Esta respuesta cubre todo, por ejemplo. un archivo como foo_folder/foo-file.jpg?1345838509fallará miserablemente con just pathinfo,
1
¡No completamente sobre el tema, pero seguro que resolvió mi problema!
Howie
77
¡No olvides nada! parse_urles para URL y pathinfoes para ruta de archivo.
Nabi KAZ
1
¿Qué quieres decir con "olvidar información de ruta"? ¡Lo usas en la solución!
Otoño Leonard
1
@AutumnLeonard No lo hace, solo mostró las diferencias entre pathinfo y parse_url.
59

También hay SplFileInfo:

$file = new SplFileInfo($path);
$ext  = $file->getExtension();

A menudo puede escribir un código mejor si pasa un objeto de este tipo en lugar de una cadena. Tu código habla más entonces. Desde PHP 5.4 esta es una línea:

$ext  = (new SplFileInfo($path))->getExtension();
hakre
fuente
Fantástico, sus objetos hasta el fondo :)
Christopher Chase
2
Tenga en cuenta que ->getExtension()está disponible en SplFileInfo desde PHP 5.3.6.
matthias
1
@matthias: Tenga en cuenta que SPL puede deshabilitarse en las versiones de PHP anteriores a la versión PHP 5.3.0. Si todavía no está ejecutando PHP 5.3 pero 5.2 o inferior, es probable que esta respuesta no se ajuste a un código estable. De lo contrario, puede estabilizar su código al requerir una versión específica de PHP y, de lo contrario, rescatarlo.
Hakre
@hakre Si bien tiene razón al decir que "se puede deshabilitar en versiones anteriores a 5.3.0", la extensión SPL se compila de forma predeterminada a partir de PHP 5.0.0. Por lo tanto, este comentario tiene sentido para las personas obligadas a usar PHP 5.2 o inferior y no quieren renunciar usando clases específicas de SPL.
matthias
sí, solo versión muerta pelusa :)
hakre
23

La respuesta de E-satis es la forma correcta de determinar la extensión del archivo.

Alternativamente, en lugar de depender de una extensión de archivo, puede usar fileinfo para determinar el tipo MIME de archivos.

Aquí hay un ejemplo simplificado de procesamiento de una imagen cargada por un usuario:

// Code assumes necessary extensions are installed and a successful file upload has already occurred

// Create a FileInfo object
$finfo = new FileInfo(null, '/path/to/magic/file');

// Determine the MIME type of the uploaded file
switch ($finfo->file($_FILES['image']['tmp_name'], FILEINFO_MIME)) {        
    case 'image/jpg':
        $im = imagecreatefromjpeg($_FILES['image']['tmp_name']);
    break;

    case 'image/png':
        $im = imagecreatefrompng($_FILES['image']['tmp_name']);
    break;

    case 'image/gif':
        $im = imagecreatefromgif($_FILES['image']['tmp_name']);
    break;
}
Toxygene
fuente
1
Esta es la ÚNICA respuesta correcta. No entiendo por qué la gente votó a otros. Sí, este enfoque exige más esfuerzos del desarrollador, pero aumenta el rendimiento (aunque poco, pero lo hace). Por favor refiérase esto .
Bhavik Shah
2
@Bhavik: En algunos casos, es posible que solo necesitemos la extensión del archivo, sobre la verificación del tipo mime. Pero la pregunta real es sobre la extensión del archivo, no sobre el tipo de archivo. Entonces esta NO es la mejor respuesta para esta pregunta. (Sin embargo, una respuesta)
Sasi Varna Kumar
este interruptor necesita un paréntesis extra
rsb2097
16

Siempre que no contenga una ruta, también puede usar:

array_pop(explode('.', $fname))

Donde $fnamees un nombre del archivo, por ejemplo: my_picture.jpg. Y el resultado sería:jpg

Anónimo
fuente
@ ¿Por qué esto tiene 3 votos negativos? está dando el resultado adecuado. Por favor explique
railsbox
No está mal, simplemente no es la mejor manera de hacerlo. Votaron por un poco de equilibrio.
Esta es la mejor manera, cuando necesita la extensión real y el nombre de archivo puede tener múltiples., Como fotos cargadas por el usuario en mi caso.
Rauli Rajande
2
Esto falla si el nombre del archivo no tiene extensión. Intente pasar "myfile" y devolverá "myfile". El valor de retorno correcto es una cadena vacía como la extensión en este caso de uso.
pmont
Esto está mal porque array_pop () lanzará un aviso porque toma un puntero como parámetro.
jurchiks
12

1) Si está usando (PHP 5> = 5.3.6) puede usar SplFileInfo :: getExtension - Obtiene la extensión del archivo

Código de ejemplo

<?php

$info = new SplFileInfo('test.png');
var_dump($info->getExtension());

$info = new SplFileInfo('test.tar.gz');
var_dump($info->getExtension());

?>

Esto dará salida

string(3) "png"
string(2) "gz"

2) Otra forma de obtener la extensión si está utilizando (PHP 4> = 4.0.3, PHP 5) es pathinfo

Código de ejemplo

<?php

$ext = pathinfo('test.png', PATHINFO_EXTENSION);
var_dump($ext);

$ext = pathinfo('test.tar.gz', PATHINFO_EXTENSION);
var_dump($ext);

?>

Esto dará salida

string(3) "png"
string(2) "gz"

// EDITAR: eliminado un corchete

Subodh Ghulaxe
fuente
12

A veces es útil no usar pathinfo($path, PATHINFO_EXTENSION). Por ejemplo:

$path = '/path/to/file.tar.gz';

echo ltrim(strstr($path, '.'), '.'); // tar.gz
echo pathinfo($path, PATHINFO_EXTENSION); // gz

También tenga en cuenta que pathinfono puede manejar algunos caracteres no ASCII (por lo general, solo los suprime de la salida). En extensiones que generalmente no son un problema, pero no está de más estar al tanto de esa advertencia.

Alix Axel
fuente
66
@ e-satis: Según Wikipedia , son dos extensiones: los sistemas de archivos tipo UNIX usan un modelo diferente sin los metadatos de extensión segregada. El carácter de punto es solo otro carácter en el nombre de archivo principal, y los nombres de archivo pueden tener múltiples extensiones, que generalmente representan transformaciones anidadas, como files.tar.gz .
Alix Axel
1
¿Y si tenemos un punto en el nombre del producto? Ej:test.19-02-2014.jpeg
Mario Radomanana
Esto fallará con /root/my.folder/my.css ltrim(strrchr($PATH, '.'),'.')funciona como pathinfo, pero sin tokenizar todo.
Ray Foss
8

La forma más sencilla de obtener la extensión de archivo en PHP es usar la función incorporada pathinfo de PHP .

$file_ext = pathinfo('your_file_name_here', PATHINFO_EXTENSION);
echo ($file_ext); // The output should be the extension of the file e.g., png, gif, or html
Shahbaz
fuente
8

También puedes probar esto (funciona en PHP 5. * y 7):

$info = new SplFileInfo('test.zip');
echo $info->getExtension(); // ----- Output -----> zip

Consejo: devuelve una cadena vacía si el archivo no tiene una extensión

pooya_sabramooz
fuente
7

Lo siento ... "Pregunta corta; pero NO respuesta corta"

Ejemplo 1 para RUTA

$path = "/home/ali/public_html/wp-content/themes/chicken/css/base.min.css";
$name = pathinfo($path, PATHINFO_FILENAME);
$ext  = pathinfo($path, PATHINFO_EXTENSION);
printf('<hr> Name: %s <br> Extension: %s', $name, $ext);

Ejemplo 2 para URL

$url = "//www.example.com/dir/file.bak.php?Something+is+wrong=hello";
$url = parse_url($url);
$name = pathinfo($url['path'], PATHINFO_FILENAME);
$ext  = pathinfo($url['path'], PATHINFO_EXTENSION);
printf('<hr> Name: %s <br> Extension: %s', $name, $ext);

Salida del ejemplo 1:

Name: base.min
Extension: css

Salida del ejemplo 2:

Name: file.bak
Extension: php

Referencias

  1. https://www.php.net/manual/en/function.pathinfo.php

  2. https://www.php.net/manual/en/function.realpath.php

  3. https://www.php.net/manual/en/function.parse-url.php

Ali
fuente
6

Una solución rápida sería algo como esto.

// Exploding the file based on the . operator
$file_ext = explode('.', $filename);

// Count taken (if more than one . exist; files like abc.fff.2013.pdf
$file_ext_count = count($file_ext);

// Minus 1 to make the offset correct
$cnt = $file_ext_count - 1;

// The variable will have a value pdf as per the sample file name mentioned above.
$file_extension = $file_ext[$cnt];
versión 2
fuente
¿Por qué no simplemente usar PHP construido en función de la finalidad para la php.net/manual/en/function.pathinfo.php en lugar de utilizar código largo
Shahbaz
1
Además del punto de Shahbaz, también puedes $file_ext = end(explode('.', $filename));hacer todo en esta respuesta en una sola línea en lugar de cuatro.
tvanc
@ Amelia ¿Qué pasa si tienes .tar.gz? No funcionará, por lo tanto, si necesita llenarse de extensiones, use las ltrim(strstr($filename, '.'), '.');extensiones de manera incorrecta gz.
Marin Sagovac
6

Aquí hay un ejemplo. Supongamos que $ filename es "example.txt",

$ext = substr($filename, strrpos($filename, '.', -1), strlen($filename));

Entonces $ ext será ".txt".

GI Joe
fuente
6

pathinfo es una matriz. Podemos verificar el nombre del directorio, el nombre del archivo, la extensión , etc.

$path_parts = pathinfo('test.png');

echo $path_parts['extension'], "\n";
echo $path_parts['dirname'], "\n";
echo $path_parts['basename'], "\n";
echo $path_parts['filename'], "\n";
Arshid KV
fuente
5
substr($path, strrpos($path, '.') + 1);
Kurt Zhong
fuente
1
Esto fallará con /root/my.folder/my.css
Ray Foss
1
Esto debe funcionar correctamente: substr ($ ruta, strrpos ($ ruta, '.') + 1); Nota: este método es más rápido que cualquier otra solución anterior. Pruebe un punto de referencia utilizando nuestro propio script.
Abbas
4

Puedes probar también esto:

 pathinfo(basename($_FILES["fileToUpload"]["name"]), PATHINFO_EXTENSION)
sonrisa 22121
fuente
4
ltrim(strstr($file_url, '.'), '.')

esta es la mejor manera si tiene nombres de archivo como name.name.name.ext (feo, pero a veces sucede

Anjani Barnwal
fuente
3

Esto funcionará

$ext = pathinfo($filename, PATHINFO_EXTENSION);
Deepika Patel
fuente
Esto ya fue respondido mucho mejor por Subodh en agosto.
Nisse Engström
3

Descubrí que las soluciones pathinfo()y SplFileInfofuncionan bien para archivos estándar en el sistema de archivos local, pero puede tener dificultades si está trabajando con archivos remotos ya que las URL para imágenes válidas pueden tener un #(identificadores de fragmentos) y / o? (parámetros de consulta) al final de la URL, que ambas soluciones tratarán (incorrectamente) como parte de la extensión del archivo.

Descubrí que esta era una forma confiable de usar pathinfo()una URL después de analizarla primero para eliminar el desorden innecesario después de la extensión del archivo:

$url_components = parse_url($url); // First parse the URL
$url_path = $url_components['path']; // Then get the path component
$ext = pathinfo($url_path, PATHINFO_EXTENSION); // Then use pathinfo()
Jonathan Ellis
fuente
3

Uso substr($path, strrpos($path,'.')+1);. Es el método más rápido de todas las comparaciones.

@Kurt Zhong ya respondió.

Veamos el resultado comparativo aquí: https://eval.in/661574

Abbas
fuente
2

Puede obtener todas las extensiones de archivo en una carpeta particular y realizar operaciones con una extensión de archivo específica:

<?php
    $files = glob("abc/*.*"); // abc is the folder all files inside folder
    //print_r($files);
    //echo count($files);
    for($i=0; $i<count($files); $i++):
         $extension = pathinfo($files[$i], PATHINFO_EXTENSION);
         $ext[] = $extension;
         // Do operation for particular extension type
         if($extension=='html'){
             // Do operation
         }
    endfor;
    print_r($ext);
?>
Samir Karmacharya
fuente
2

Házlo más rápido.

Las llamadas de bajo nivel deben ser muy rápidas, así que pensé que valía la pena investigar un poco. Probé algunos métodos (con varias longitudes de cadena, longitudes de extensión, múltiples ejecuciones cada uno), aquí hay algunos razonables:

function method1($s) {return preg_replace("/.*\./","",$s);} // edge case problem
function method2($s) {preg_match("/\.([^\.]+)$/",$s,$a);return $a[1];}
function method3($s) {$n = strrpos($s,"."); if($n===false) return "";return substr($s,$n+1);}
function method4($s) {$a = explode(".",$s);$n = count($a); if($n==1) return "";return $a[$n-1];}
function method5($s) {return pathinfo($s, PATHINFO_EXTENSION);}

Los resultados no fueron muy sorprendentes. Pobre pathinfoes (¡con diferencia!) El más lento (parece que está tratando de analizar todo y luego soltar todas las partes innecesarias), y method3()(strrpos) es el más rápido, con diferencia:

Original filename was: something.that.contains.dots.txt
Running 50 passes with 10000 iterations each
Minimum of measured times per pass:

    Method 1:   312.6 mike  (response: txt) // preg_replace
    Method 2:   472.9 mike  (response: txt) // preg_match
    Method 3:   167.8 mike  (response: txt) // strrpos
    Method 4:   340.3 mike  (response: txt) // explode
    Method 5:  2311.1 mike  (response: txt) // pathinfo  <--------- poor fella

NOTA: el primer método tiene un efecto secundario: devuelve el nombre completo cuando no hay extensión. Seguramente no tendría sentido medirlo con un strpos adicional para evitar este comportamiento.

Conclusión

Esto se parece al Camino del Samurai:

function fileExtension($s) {
    $n = strrpos($s,".");
    return ($n===false) ? "" : substr($s,$n+1);
}
dkellner
fuente
1

Si está buscando velocidad (como en un enrutador), probablemente no quiera tokenizar todo. Muchas otras respuestas fallarán con/root/my.folder/my.css

ltrim(strrchr($PATH, '.'),'.');
Ray Foss
fuente
1

Aunque la "mejor manera" es discutible, creo que esta es la mejor manera por algunas razones:

function getExt($path)
{
    $basename = basename($path);
    return substr($basename, strlen(explode('.', $basename)[0]) + 1);
}
  1. Funciona con múltiples partes en una extensión, p. Ej. tar.gz
  2. Código corto y eficiente
  3. Funciona con un nombre de archivo y una ruta completa
Dan Bray
fuente
1

En mi opinión, esta es la mejor manera si tiene nombres de archivo como name.name.name.ext (feo, pero a veces sucede):

$ext     = explode('.', $filename); // Explode the string
$ext_len = count($ext) - 1; // Count the array -1 (because count() starts from 1)
$my_ext  = $ext[$ext_len]; // Get the last entry of the array

echo $my_ext;
Tommy89
fuente
1

$ext = preg_replace('/^.*\.([^.]+)$/D', '$1', $fileName);

Enfoque preg_replace usamos búsqueda y reemplazo de expresiones regulares. En la función preg_replace, el primer parámetro es el patrón de la búsqueda, el segundo parámetro $ 1 es una referencia a lo que coincida con el primer (. *) Y el tercer parámetro es el nombre del archivo.

Otra forma, también podemos usar strrpos para encontrar la posición de la última aparición de un '.' en un nombre de archivo e incremente esa posición en 1 para que explote la cadena desde (.)

$ext = substr($fileName, strrpos($fileName, '.') + 1);

Sai Kiran Sangam
fuente
0

En realidad, estaba buscando eso.

<?php

$url = 'http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ';
$tmp = @parse_url($url)['path'];
$ext = pathinfo($tmp, PATHINFO_EXTENSION);

var_dump($ext);
Fred
fuente
-1

Utilizar

str_replace('.', '', strrchr($file_name, '.'))

para una recuperación rápida de extensión (si sabe con certeza que su nombre de archivo tiene uno).

AlexB
fuente