¿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.


15

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


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"

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


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();

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;
}

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


@ ¿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


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.


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

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


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


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];

¿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".


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";

5
substr($path, strrpos($path, '.') + 1);

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)

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



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()

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


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);
?>

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);
}

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, '.'),'.');

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

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;

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);


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);

-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).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.