Jak uzyskać rozszerzenie pliku w PHP?


723

To pytanie można przeczytać w dowolnym miejscu w Internecie z różnymi odpowiedziami:

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

itp.

Jednak zawsze istnieje „najlepszy sposób” i powinno być w przypadku przepełnienia stosu.



5
Jeszcze jednym sposobem na uzyskanie rozszerzenia jeststrrchr($filename, '.');
verybadbug

Odpowiedzi:


1776

Ludzie z innych języków skryptowych zawsze myślą, że ich jest lepszy, ponieważ mają wbudowaną funkcję, aby to zrobić, a nie PHP (patrzę teraz na Pythonistas :-)).

W rzeczywistości istnieje, ale niewiele osób o tym wie. Poznaj pathinfo():

$ext = pathinfo($filename, PATHINFO_EXTENSION);

Jest to szybkie i wbudowane. pathinfo()może dać ci inne informacje, takie jak ścieżka kanoniczna, w zależności od stałej, którą do niej przekazujesz.

Pamiętaj, że jeśli chcesz poradzić sobie ze znakami spoza ASCII, musisz najpierw ustawić ustawienia regionalne. NA PRZYKŁAD:

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

Pamiętaj też, że nie bierze to pod uwagę zawartości pliku ani typu MIME, dostajesz tylko rozszerzenie. Ale o to prosiłeś.

Na koniec zauważ, że działa to tylko dla ścieżki pliku, a nie ścieżki zasobów URL, która jest objęta PARSE_URL.

Cieszyć się


62
Chciałbym móc to zagłosować dwa razy. Nie mogę powiedzieć, ile kodu udało mi się zastąpić za pomocą pathinfo
Mark Biek,

8
Ja też. Dlatego umieściłem to tutaj!
e-satis

7
Co wiadomo, okazuje się, że jest najlepszy sposób.
Ben

19
@khizaransari Powinieneś poszukać innego dostawcy hostingu, ten, który masz, jest głupi. Naprawdę mam na myśli. Nie ma żadnego powodu, aby wyłączyć tę funkcję. Powiedz im to. Aby obejść function get_ext($fname){ return substr($fname, strrpos($fname, ".") + 1); }ten problem : upewnij się, że plik ma rozszerzenie, ponieważ może on zrobić wszystko, gdy podasz ścieżkę jako argument!
Luc

12
mój pomysł na PHP w porównaniu do Pythona zmienił się całkowicie teraz, gdy wiem o tej funkcji: O
Tommaso Barbugli

166

pathinfo()

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

echo $path_info['extension']; // "bill"

14
Od PHP 5.5 ->echo pathinfo('/foo/bar/baz.bill')['extension'];
Salman A

1
Działa to nawet na tym poziomie (Twitter json): $ ext = pathinfo ($ result-> Extended_entities-> media [0] -> video_info-> warianty [1] -> url, PATHINFO_EXTENSION);
KJS,

100

Przykładowy adres URL: http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ

A) Nie używaj sugerowanych niebezpiecznychPATHINFO :

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) Użyj 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'

BONUS: Wyświetl wszystkie natywne przykłady PHP


3
Ta odpowiedź obejmuje wszystko, np. plik typu foo_folder/foo-file.jpg?1345838509zawiedzie nieszczęśliwie z just pathinfo, thanx

1
Nie do końca na ten temat, ale z pewnością rozwiązało mój problem!
Howie

7
Nie zapomnij o niczym! parse_urldotyczy adresu URL i pathinfościeżki pliku.
Nabi KAZ

1
Co masz na myśli „zapomnij informacje o ścieżce”? Używasz go w rozwiązaniu!
Jesień Leonard,

1
@AutumnLeonard Nie, on po prostu pokazał różnice między pathinfo a parse_url.

59

Istnieje również SplFileInfo:

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

Często możesz napisać lepszy kod, jeśli podasz taki obiekt zamiast łańcucha. Twój kod mówi bardziej niż. Od PHP 5.4 jest to jedna linijka:

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

Fantastyczne, jego obiekty aż do samego końca :)
Christopher Chase

2
Pamiętaj, że ->getExtension()jest dostępny w SplFileInfo od PHP 5.3.6.
Matthias

1
@matthias: Należy pamiętać, że SPL można wyłączyć w wersjach PHP wcześniejszych niż PHP 5.3.0. Jeśli nadal nie korzystasz z PHP 5.3, ale 5.2 lub starszego, ta odpowiedź najprawdopodobniej nie pasowała do stabilnego kodu. W przeciwnym razie możesz ustabilizować swój kod, wymagając konkretnej wersji PHP i w inny sposób ratować.
hakre

@hakre Chociaż masz rację mówiąc, że „można go wyłączyć w wersjach wcześniejszych niż 5.3.0”, rozszerzenie SPL jest jednak domyślnie kompilowane od wersji PHP 5.0.0. Tak więc ten komentarz ma sens dla osób zmuszonych do korzystania z PHP 5.2 lub niższego i nie chce rezygnować z używania określonych klas SPL.
Matthias

tak, tylko martwa wersja puchu :)
hakre

23

Odpowiedź E-satis to właściwy sposób na określenie rozszerzenia pliku.

Alternatywnie, zamiast polegać na rozszerzeniu plików, możesz użyć fileinfo do określenia typu pliku MIME.

Oto uproszczony przykład przetwarzania obrazu przesłanego przez użytkownika:

// 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
To jest jedyna poprawna odpowiedź. Nie rozumiem, dlaczego ludzie głosowali na innych. Tak, to podejście wymaga więcej wysiłku ze strony programisty, ale zwiększa wydajność (choć niewiele, ale tak jest). Proszę to odnieść .
Bhavik Shah

2
@Bhavik: W niektórych przypadkach możemy potrzebować tylko rozszerzenia pliku, dotyczą one sprawdzania typu MIME. Ale rzeczywiste pytanie dotyczy rozszerzenia pliku, a nie typu pliku. To NIE jest najlepsza odpowiedź na to pytanie. (jeszcze odpowiedź)
Sasi varna kumar

ten przełącznik wymaga dodatkowego nawiasu
rsb2097

16

O ile nie zawiera ścieżki, możesz także użyć:

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

Gdzie $fnameznajduje się nazwa pliku, na przykład: my_picture.jpg. Rezultatem byłoby:jpg


@Dlaczego to ma 3 głosy negatywne? daje właściwy wynik. Wyjaśnij
railsbox

To nie jest źle, to nie jest najlepszy sposób, aby to zrobić. Poproszono o trochę równowagi.

Jest to najlepszy sposób, gdy potrzebujesz prawdziwego rozszerzenia, a nazwa pliku może zawierać wiele plików .s, jak w moim przypadku zdjęcia przesłane przez użytkownika.
Rauli Rajande

2
To się nie powiedzie, jeśli nazwa pliku nie ma rozszerzenia. Spróbuj przekazać „mój plik”, a zwróci „mój plik”. Prawidłowa wartość zwracana to pusty ciąg znaków jako rozszerzenie w tym przypadku użycia.
pmont

Jest to niewłaściwe w tym, że array_pop () wyrzuci powiadomienie, ponieważ przyjmuje wskaźnik jako parametr.
jurchiks

12

1) Jeśli używasz (PHP 5> = 5.3.6) , możesz użyć SplFileInfo :: getExtension - Pobiera rozszerzenie pliku

Przykładowy kod

<?php

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

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

?>

To wyjdzie

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

2) Innym sposobem uzyskania rozszerzenia, jeśli używasz (PHP 4> = 4.0.3, PHP 5), jest pathinfo

Przykładowy kod

<?php

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

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

?>

To wyjdzie

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

// EDYCJA: usunięto nawias klamrowy


12

Czasami dobrze jest nie używać pathinfo($path, PATHINFO_EXTENSION). Na przykład:

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

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

Zauważ też, że pathinfonie obsługuje niektórych znaków spoza ASCII (zwykle po prostu pomija je w danych wyjściowych). W rozszerzeniach zwykle nie stanowi to problemu, ale nie zaszkodzi być świadomym tego ostrzeżenia.


6
@ e-satis: Według Wikipedii są to dwa rozszerzenia: Systemy plików podobne do UNIXa używają innego modelu bez segregowanych metadanych rozszerzeń. Znak kropki to po prostu kolejny znak w głównej nazwie pliku, a nazwy plików mogą mieć wiele rozszerzeń, zwykle reprezentujących zagnieżdżone transformacje, takie jak files.tar.gz .
Alix Axel,

1
A jeśli mamy kropkę w nazwie produktu? Np .:test.19-02-2014.jpeg
Mario Radomanana

To się nie powiedzie z /root/my.folder/my.css ltrim(strrchr($PATH, '.'),'.')działa jak pathinfo, ale bez tokenizacji wszystkiego.
Ray Foss,

8

Najprostszym sposobem uzyskania rozszerzenia pliku w PHP jest użycie wbudowanej funkcji PHP pathinfo .

$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

Możesz spróbować również tego (działa na PHP 5. * i 7):

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

Wskazówka: zwraca pusty ciąg, jeśli plik nie ma rozszerzenia


7

Przepraszam ... „Krótkie pytanie; ale NIE krótka odpowiedź”

Przykład 1 dla 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);

Przykład 2 dla adresu 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);

Wyjście z przykładu 1:

Name: base.min
Extension: css

Wyjście z przykładu 2:

Name: file.bak
Extension: php

Bibliografia

  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

Szybka poprawka byłaby czymś takim.

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

Dlaczego nie skorzystać z wbudowanej funkcji php do celów php.net/manual/en/function.pathinfo.php zamiast długiego kodu
Shahbaz

1
Oprócz argumentu Shahbaza możesz także $file_ext = end(explode('.', $filename));zrobić wszystko, co w tej odpowiedzi, w jednym wierszu zamiast czterech.
tvanc

@Amelia Co jeśli masz .tar.gz. To nie zadziała, więc jeśli potrzebujesz pełnego rozszerzenia, użyj np. ltrim(strstr($filename, '.'), '.');Pełnego rozszerzenia zamiast niepoprawnie jak gz.
Marin Sagovac

6

Oto przykład. Załóżmy, że $ filename to „example.txt”,

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

Zatem $ ext będzie miał postać „.txt”.


6

pathinfo to tablica. Możemy sprawdzić nazwę katalogu, nazwę pliku, rozszerzenie itp .:

$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
Nie powiedzie się to z /root/my.folder/my.css
Ray Foss,

1
To musi działać poprawnie: substr ($ path, strrpos ($ path, '.') + 1); Uwaga: ta metoda jest szybsza niż jakiekolwiek inne powyższe rozwiązania. Wypróbuj test porównawczy, korzystając z własnego skryptu.
Abbas,

4

Możesz także spróbować:

 pathinfo(basename($_FILES["fileToUpload"]["name"]), PATHINFO_EXTENSION)

4
ltrim(strstr($file_url, '.'), '.')

jest to najlepszy sposób, jeśli masz nazwy plików takie jak nazwa.nazwa.nazwa.ext (brzydkie, ale czasem się zdarza



3

Odkryłem, że rozwiązania pathinfo()i SplFileInfodziałają dobrze dla standardowych plików w lokalnym systemie plików, ale możesz napotkać trudności, jeśli pracujesz ze zdalnymi plikami, ponieważ adresy URL prawidłowych obrazów mogą mieć #(identyfikatory fragmentów) i / lub ?(parametry zapytania) na końcu adresu URL, który oba te rozwiązania (nieprawidłowo) będą traktować jako część rozszerzenia pliku.

Odkryłem, że był to niezawodny sposób na użycie pathinfo()adresu URL po pierwszym analizowaniu go w celu usunięcia niepotrzebnego bałaganu po rozszerzeniu pliku:

$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

Zastosowanie substr($path, strrpos($path,'.')+1);. Jest to najszybsza metoda ze wszystkich porównań.

@Kurt Zhong już odpowiedział.

Sprawdźmy wynik porównawczy tutaj: https://eval.in/661574


2

Możesz pobrać wszystkie rozszerzenia plików w określonym folderze i wykonywać operacje z określonym rozszerzeniem pliku:

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

Rób to szybciej.

Połączenia na niskim poziomie muszą być bardzo szybkie, więc pomyślałem, że warto było to zbadać. Wypróbowałem kilka metod (z różnymi długościami ciągów, długościami przedłużeń, wieloma biegami), oto kilka rozsądnych:

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

Wyniki nie były bardzo zaskakujące. Słaba pathinfojest (zdecydowanie!) Najwolniejsza (wygląda na to, że próbuje przeanalizować całość, a następnie upuścić wszystkie niepotrzebne części) - a method3()(strrpos) jest zdecydowanie najszybsza:

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

UWAGA: pierwsza metoda ma efekt uboczny: zwraca całą nazwę, gdy nie ma rozszerzenia. Z pewnością nie ma sensu mierzyć go dodatkowymi strpos, aby uniknąć takiego zachowania.

Wniosek

Wygląda to jak Droga Samuraja:

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

1

Jeśli szukasz szybkości (na przykład w routerze), prawdopodobnie nie chcesz tokenizować wszystkiego. Wiele innych odpowiedzi się nie powiedzie/root/my.folder/my.css

ltrim(strrchr($PATH, '.'),'.');

1

Chociaż „najlepszy sposób” jest dyskusyjny, uważam, że jest to najlepszy sposób z kilku powodów:

function getExt($path)
{
    $basename = basename($path);
    return substr($basename, strlen(explode('.', $basename)[0]) + 1);
}
  1. Działa z wieloma częściami do rozszerzenia, np tar.gz
  2. Krótki i wydajny kod
  3. Działa zarówno z nazwą pliku, jak i pełną ścieżką

1

IMO, jest to najlepszy sposób, jeśli masz nazwy plików takie jak name.name.name.ext (brzydkie, ale czasem się zdarza):

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

podejście preg_replace używamy wyszukiwania wyrażeń regularnych i zastępujemy. W funkcji preg_replace pierwszym parametrem jest wzorzec wyszukiwania, drugi parametr $ 1 jest odniesieniem do wszystkiego, co pasuje do pierwszego (. *), A trzeci parametr to nazwa pliku.

Innym sposobem możemy również użyć strrpos, aby znaleźć pozycję ostatniego wystąpienia „.” w nazwie pliku i zwiększaj tę pozycję o 1, aby eksplodował ciąg z (.)

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


0

Właściwie tego szukałem.

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

Posługiwać się

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

w celu szybkiego pobrania rozszerzenia (jeśli wiesz na pewno, że twoja nazwa pliku go posiada).

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.