Como obtenho uma extensão de arquivo em PHP?

723

Esta é uma pergunta que você pode ler em qualquer lugar da Web com várias respostas:

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

No entanto, sempre existe "o melhor caminho" e deve estar no Stack Overflow.

e-satis
fonte
15
Fonte de pergunta e resposta: cowburn.info/2008/01/13/get-file-extension-comparison
Salathe
5
Mais uma maneira de obter ext éstrrchr($filename, '.');
verybadbug

Respostas:

1776

Pessoas de outras linguagens de script sempre acham que a deles é melhor porque elas têm uma função interna para fazer isso e não o PHP (estou vendo os Pythonistas agora :-)).

De fato, existe, mas poucas pessoas sabem disso. Conheça pathinfo():

$ext = pathinfo($filename, PATHINFO_EXTENSION);

Isso é rápido e embutido. pathinfo()pode fornecer outras informações, como caminho canônico, dependendo da constante que você passar para ele.

Lembre-se de que, se você quiser lidar com caracteres não ASCII, precisará primeiro definir o código do idioma. POR EXEMPLO:

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

Além disso, observe que isso não leva em consideração o conteúdo do arquivo ou o tipo MIME, você só obtém a extensão. Mas é o que você pediu.

Por fim, observe que isso funciona apenas para um caminho de arquivo, não um caminho de recursos de URL, coberto usando PARSE_URL.

Aproveitar

e-satis
fonte
62
Eu gostaria de poder votar duas vezes. Eu não posso te dizer o quanto código que eu tenho sido capaz de substituir usando pathinfo
Mark Biek
8
Eu também. É por isso que eu coloco aqui!
E-satis
7
Como sabemos, acontece que existe a melhor maneira.
Ben
19
@khizaransari Você deve procurar outro provedor de hospedagem, o que você conseguiu é estúpido. Sério, eu quero dizer isso. Não há razão alguma para desativar esta função. Diga isso a eles. Como solução alternativa: function get_ext($fname){ return substr($fname, strrpos($fname, ".") + 1); }verifique se o arquivo possui uma extensão; ele pode fazer qualquer coisa quando você passa um caminho como argumento!
20912 Luc Luc
12
minha idéia de PHP em comparação com python mudou completamente agora que eu sei sobre essa função: O
Tommaso Barbugli
166

pathinfo()

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

echo $path_info['extension']; // "bill"
Adam Wright
fonte
14
Desde PHP 5.5 ->echo pathinfo('/foo/bar/baz.bill')['extension'];
Salman A
1
Isso funciona até nesse nível (Twitter json): $ ext = pathinfo ($ result-> extended_entities-> media [0] -> video_info-> variantes [1] -> url, PATHINFO_EXTENSION);
KJS 04/12
101

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

A) Não use sugestões 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'

BÔNUS: Veja todos os exemplos nativos do PHP

T.Todua
fonte
3
Esta resposta cobre tudo, por exemplo. um arquivo como foo_folder/foo-file.jpg?1345838509irá falhar miseravelmente com apenas pathinfo, thanx
1
Não completamente sobre o assunto, mas com certeza resolveu o meu problema!
Howie
7
Não esqueça nada! parse_urlé para URL e pathinfoé para o caminho do arquivo.
Nabi KAZ
1
O que você quer dizer com "esquecer informações do caminho"? Você o usa na solução!
Autumn Leonard
1
@AutumnLeonard Ele não mostra, ele apenas mostrou as diferenças entre pathinfo e parse_url.
59

Há também SplFileInfo:

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

Freqüentemente, você pode escrever um código melhor se passar um objeto assim ao invés de uma string. Seu código está mais falando então. Desde o PHP 5.4, este é um recurso:

$ext  = (new SplFileInfo($path))->getExtension();
hakre
fonte
Fantástico, seus objetos todo o caminho :)
Christopher perseguição
2
Esteja ciente de que ->getExtension()está disponível no SplFileInfo desde o PHP 5.3.6.
Matthias
1
@matthias: Esteja ciente de que o SPL pode ser desativado nas versões PHP anteriores à versão 5.3.0 do PHP. Se você ainda não está executando o PHP 5.3, mas 5.2 ou inferior, é provável que esta resposta não se encaixe no código estável. Caso contrário, você pode estabilizar seu código exigindo uma versão PHP específica e, caso contrário, resgatar.
hakre
@hakre Embora você esteja certo ao dizer que "pode ​​ser desativado em versões anteriores à 5.3.0", a extensão SPL é compilada por padrão a partir do PHP 5.0.0. Portanto, esse comentário faz sentido para as pessoas forçadas a usar o PHP 5.2 ou inferior e não querem renunciar usando classes SPL específicas.
Matthias
sim, apenas a versão morto fluff :)
hakre
23

A resposta do E-satis é a maneira correta de determinar a extensão do arquivo.

Como alternativa, em vez de depender de uma extensão de arquivos, você pode usar o fileinfo para determinar o tipo de MIME dos arquivos.

Aqui está um exemplo simplificado de processamento de uma imagem carregada por um usuário:

// 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;
}
Toxigênio
fonte
1
Esta é a única resposta correta. Não entendo por que as pessoas votaram nos outros. Sim, essa abordagem exige mais esforços do desenvolvedor, mas aumenta o desempenho (embora pouco, mas exige). Por favor, consulte isso .
Bhavik Shah
2
@Bhavik: Em alguns casos, podemos precisar apenas da extensão do arquivo, sobre a verificação do tipo mime. Mas a questão real é sobre extensão de arquivo, não tipo de arquivo. Portanto, essa NÃO é a melhor resposta para esta pergunta. (ainda uma resposta)
Sasi varna kumar
este interruptor precisa de um parêntese adicional
rsb2097
16

Contanto que ele não contenha um caminho, você também pode usar:

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

Onde $fnameé um nome do arquivo, por exemplo: my_picture.jpg. E o resultado seria:jpg

Anônimo
fonte
@Por que isso tem 3 votos negativos? está dando resultado adequado. Por favor, explique
railsbox
Não está errado, apenas não é a melhor maneira de fazê-lo. Votado para um pouco de equilíbrio.
Essa é a melhor maneira, quando você precisa da extensão real e o nome do arquivo pode ter vários .s, como fotos enviadas por usuários no meu caso.
Rauli Rajande
2
Isso falhará se o nome do arquivo não tiver extensão. Tente passar "myfile" e ele retornará "myfile". O valor de retorno correto é uma sequência vazia como a extensão nesse caso de uso.
pmont
Isso está errado, pois array_pop () lançará um aviso porque ele recebe um ponteiro como parâmetro.
31415 jorgiks
12

1) Se você estiver usando (PHP 5> = 5.3.6), poderá usar SplFileInfo :: getExtension - Obtém a extensão do arquivo

Código de exemplo

<?php

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

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

?>

Isso produzirá

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

2) Outra maneira de obter a extensão se você estiver usando (PHP 4> = 4.0.3, PHP 5) é pathinfo

Código de exemplo

<?php

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

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

?>

Isso produzirá

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

// EDIT: removeu um colchete

Subodh Ghulaxe
fonte
12

Às vezes é útil não usar pathinfo($path, PATHINFO_EXTENSION). Por exemplo:

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

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

Observe também que pathinfofalha ao manipular alguns caracteres não-ASCII (geralmente apenas os suprime da saída). Em extensões que geralmente não são um problema, mas não faz mal estar ciente dessa advertência.

Alix Axel
fonte
6
@ e-satis: Segundo a Wikipedia , existem duas extensões: Os sistemas de arquivos do tipo UNIX usam um modelo diferente sem os metadados de extensão segregados. O caractere de ponto é apenas outro caractere no nome do arquivo principal e os nomes de arquivos podem ter várias extensões, geralmente representando transformações aninhadas, como files.tar.gz .
Alix Axel
1
E se tivermos ponto no nome do produto? Ex:test.19-02-2014.jpeg
Mario Radomanana 26/03
Isso falhará com /root/my.folder/my.css ltrim(strrchr($PATH, '.'),'.')funciona como pathinfo, mas sem tokenizar tudo.
Raio Foss
8

A maneira mais simples de obter extensão de arquivo no PHP é usar a função interna pathinfo do 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
fonte
8

Você pode tentar também isso (funciona no PHP 5. * e 7):

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

Dica: retorna uma string vazia se o arquivo não tiver uma extensão

pooya_sabramooz
fonte
7

Desculpe ... "Pergunta curta; mas NÃO resposta curta"

Exemplo 1 para PATH

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

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

Saída do exemplo 1:

Name: base.min
Extension: css

Saída do exemplo 2:

Name: file.bak
Extension: php

Referências

  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

Todos
fonte
6

Uma solução rápida seria algo assim.

// 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];
versão 2
fonte
Porque não basta usar php construído em função com a finalidade php.net/manual/en/function.pathinfo.php em vez de usar código de longa
Shahbaz
1
Além do argumento de Shahbaz, você também pode $file_ext = end(explode('.', $filename));fazer tudo nesta resposta em uma única linha, em vez de quatro.
Tv
@Amelia E se você tiver .tar.gz. Isso não funcionará; portanto, se você precisar usar extensões, use-as como ltrim(strstr($filename, '.'), '.');incorretamente gz.
Marin Sagovac
6

Aqui está um exemplo. Suponha que $ filename seja "example.txt",

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

Então $ ext será ".txt".

GI Joe
fonte
6

pathinfo é uma matriz. Podemos verificar o nome do diretório, nome do arquivo, extensão , 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
fonte
5
substr($path, strrpos($path, '.') + 1);
Kurt Zhong
fonte
1
Isto irá falhar com /root/my.folder/my.css
Ray Foss
1
Isso deve funcionar corretamente: substr ($ path, strrpos ($ path, '.') + 1); Nota: este método é mais rápido que qualquer outra solução acima. Experimente uma referência usando nosso próprio script.
Abbas
4

Você também pode tentar isso:

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

essa é a melhor maneira se você tiver nomes de arquivos como name.name.name.ext (feio, mas às vezes acontece

Anjani Barnwal
fonte
3

Isso vai funcionar

$ext = pathinfo($filename, PATHINFO_EXTENSION);
Deepika Patel
fonte
Isso já foi respondido muito melhor pela Subodh em agosto.
Nisse Engström
3

Descobri que as soluções pathinfo()e SplFileInfofuncionam bem para arquivos padrão no sistema de arquivos local, mas você pode ter dificuldades se estiver trabalhando com arquivos remotos, pois os URLs para imagens válidas podem ter um #(identificador de fragmento) e / ou? (parâmetros de consulta) no final do URL, que ambas as soluções (incorretas) tratam como parte da extensão do arquivo.

Eu achei que essa era uma maneira confiável de usar pathinfo()um URL depois de analisá-lo para remover a confusão desnecessária após a extensão do arquivo:

$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
fonte
3

Use substr($path, strrpos($path,'.')+1);. É o método mais rápido de todas as comparações.

@ Kurt Zhong já respondeu.

Vamos verificar o resultado comparativo aqui: https://eval.in/661574

Abbas
fonte
2

Você pode obter todas as extensões de arquivo em uma pasta específica e executar operações com uma extensão de arquivo 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
fonte
2

Faça mais rápido.

As chamadas de baixo nível precisam ser muito rápidas, então pensei que valia a pena pesquisar. Eu tentei alguns métodos (com vários comprimentos de string, comprimentos de extensão, várias execuções cada), eis alguns razoáveis:

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

Os resultados não foram muito surpreendentes. Pobre pathinfoé (de longe!) O mais lento (parece que ele está tentando analisar a coisa toda e depois largar todas as partes desnecessárias) - e method3()(strrpos) é o mais rápido, de longe:

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: o primeiro método tem um efeito colateral: retorna o nome inteiro quando não há extensão. Certamente não faria sentido medi-lo com outras strops para evitar esse comportamento.

Conclusão

Parece o Caminho do Samurai:

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

Se você está procurando velocidade (como em um roteador), provavelmente não deseja tokenizar tudo. Muitas outras respostas falharão com/root/my.folder/my.css

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

Embora o "melhor caminho" seja discutível, acredito que seja o melhor por alguns motivos:

function getExt($path)
{
    $basename = basename($path);
    return substr($basename, strlen(explode('.', $basename)[0]) + 1);
}
  1. Funciona com várias partes em uma extensão, por exemplo tar.gz
  2. Código curto e eficiente
  3. Funciona com um nome de arquivo e um caminho completo
Dan Bray
fonte
1

IMO, esta é a melhor maneira se você tiver nomes de arquivos como name.name.name.ext (feio, mas às vezes acontece):

$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
fonte
1

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

preg_replace, estamos usando a pesquisa de expressão regular e substituí-la. Na função preg_replace, o primeiro parâmetro é padrão para a pesquisa, o segundo parâmetro $ 1 é uma referência ao que for correspondido pelo primeiro (. *) E o terceiro parâmetro é o nome do arquivo.

Outra maneira, também podemos usar strrpos para encontrar a posição da última ocorrência de um '.' em um nome de arquivo e aumente essa posição em 1 para que ela exploda a string de (.)

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

Sai Kiran Sangam
fonte
0

Na verdade, eu estava procurando por isso.

<?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
fonte
-1

Usar

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

para uma recuperação rápida da extensão (se você souber com certeza o nome do seu arquivo).

AlexB
fonte