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.



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


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"

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


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

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

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


@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


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.


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

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


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


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

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


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

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

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)

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



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

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


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

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

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

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

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;

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


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

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.