PHP'de dosya uzantısını nasıl edinebilirim?


724

Bu, web'in her yerinde çeşitli cevaplarla okuyabileceğiniz bir soru:

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

vb.

Ancak, her zaman "en iyi yol" vardır ve Yığın Taşması üzerinde olmalıdır.



5
strrchr($filename, '.');
Ext

Yanıtlar:


1777

Diğer betik dillerinden insanlar her zaman onların daha iyi olduğunu düşünüyorlar çünkü PHP'yi değil, bunu yapmak için yerleşik bir fonksiyona sahipler (şu an Pythonistas'a bakıyorum :-)).

Aslında var, ama çok az insan biliyor. Tanışma pathinfo():

$ext = pathinfo($filename, PATHINFO_EXTENSION);

Bu hızlı ve yerleşiktir. pathinfo()size geçtiğiniz sabite bağlı olarak kanonik yol gibi başka bilgiler verebilir.

ASCII olmayan karakterlerle başa çıkmak istiyorsanız, önce yerel ayarı ayarlamanız gerektiğini unutmayın. ÖRNEĞİN:

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

Ayrıca, bunun dosya içeriğini veya mime türünü dikkate almadığını unutmayın, yalnızca uzantıyı alırsınız. Ama istediğin buydu.

Son olarak, bunun PARSE_URL kullanılarak kapsanan URL kaynakları yolu için değil, yalnızca dosya yolu için çalıştığını unutmayın.

Zevk almak


62
Keşke iki kere oy verebilseydim.
Pathinfo

8
Ben de öyle. Bu yüzden buraya koydum!
e-satis

7
Whaddaya bilir, en iyi yol var.
Ben

19
@khizaransari Başka bir barındırma sağlayıcısı aramalısınız, sahip olduğunuz aptalca. Gerçekten, demek istediğim. Bu işlevi devre dışı bırakmak için hiçbir neden yoktur . Söyle onlara. Geçici bir çözüm olarak: function get_ext($fname){ return substr($fname, strrpos($fname, ".") + 1); }Dosyanın bir uzantıya sahip olduğundan emin olun, bağımsız değişken olarak bir yoldan geçtiğinizde her şeyi yapabilir!
Luc

12
python karşılaştırıldığında PHP benim fikrim tamamen bu işlevi hakkında biliyorum tamamen değişti: O
Tommaso Barbugli

166

pathinfo()

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

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

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

1
Bu bile bu seviyede çalışır (Twitter json): $ ext = pathinfo ($ sonuç-> genişletilmiş_entlikler-> medya [0] -> video_info-> varyantlar [1] -> url, PATHINFO_EXTENSION);
KJS

101

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

A) Önerilen güvensiz kullanımı kullanmayınPATHINFO :

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) PARSE_URL kullanın :

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: Tüm yerel PHP örneklerini görüntüle


3
Bu cevap her şeyi kapsar örn. gibi bir dosya foo_folder/foo-file.jpg?1345838509sadece pathinfo, thanx ile sefil başarısız olacak

1
Tamamen konu değil, ama kesinlikle sorunumu çözdü!
Howie

7
Hiçbir şey unutma! parse_urlURL içindir ve pathinfodosya yolu içindir.
Nabi KAZ

1
Ne demek "yol bilgisini unut"? Çözeltide kullanıyorsunuz!
Sonbahar Leonard

1
@AutumnLeonard Yapmaz, sadece pathinfo ve parse_url arasındaki farkları gösterdi.

59

Ayrıca SplFileInfo:

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

Genellikle böyle bir nesneyi dize yerine geçirirseniz daha iyi kod yazabilirsiniz. Kodunuz daha iyi konuşuyor. PHP 5.4'ten beri bu tek satırlıdır:

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

Fantastik, Nesneleri tamamen aşağı :)
Christopher Chase

2
->getExtension()PHP 5.3.6'dan beri SplFileInfo'da mevcut olduğunu lütfen unutmayın.
matthias

1
@matthias: Lütfen SPL'nin PHP 5.3.0 sürümünden önceki PHP sürümlerinde devre dışı bırakılabileceğini unutmayın. Hala PHP 5.3 ama 5.2 ya da daha düşük bir sürümü kullanmıyorsanız, bu cevap büyük olasılıkla kararlı kod için uygun değildir. Aksi takdirde, kodunuzu belirli bir PHP sürümü gerektirerek sabitleyebilir ve başka şekilde kurtarabilirsiniz.
hakre

@hakre "5.3.0 öncesi sürümlerde devre dışı bırakılabilir" demeyi haklı çıkarsanız da SPL uzantısı PHP 5.0.0'dan itibaren varsayılan olarak derlenmiştir. Bu nedenle bu yorum PHP 5.2 veya daha düşük bir sürümünü kullanmaya zorlanan ve belirli SPL sınıflarını kullanarak istifa etmek istemeyen insanlar için gerçekten anlamlı.
matthias

evet, sadece ölü sürüm kabartmak :)
hakre

23

E-satis yanıtı, dosya uzantısını belirlemenin doğru yoludur.

Alternatif olarak, bir dosya uzantısına güvenmek yerine, MIME türündeki dosyaları belirlemek için fileinfo kullanabilirsiniz .

Aşağıda, kullanıcı tarafından yüklenen bir resmi işlemenin basitleştirilmiş bir örneği verilmiştir:

// 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
Bu SADECE doğru cevaptır. İnsanların neden başkalarına oy verdiğini anlamıyorum. Evet, bu yaklaşım geliştiriciden daha fazla çaba gerektirir, ancak performansı artırır (çok az olmasına rağmen, ama öyle). Bakınız bu .
Bhavik Şah

2
@Bhavik: Bazı durumlarda sadece dosya uzantısına ihtiyacımız olabilir, bunlar mime tipi kontrolü ile ilgilidir. Ancak asıl soru dosya türüyle değil dosya uzantısıyla ilgilidir. Yani bu soru için en iyi cevap bu DEĞİLDİR. (henüz bir cevap)
Sasi varna kumar

bu anahtar ekstra bir parantez gerekiyor
rsb2097

16

Bir yol içermediği sürece şunları da kullanabilirsiniz:

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

Nerede $fnameörneğin dosyanın bir isimdir: my_picture.jpg. Ve sonuç şöyle olur:jpg


@Bunun neden 3 downvotes var? doğru sonucu veriyor. Lütfen açıklayın
railsbox

Yanlış değil, bunu yapmanın en iyi yolu değil. Biraz dengeye yükseldi.

Gerçek uzantıya ihtiyaç duyduğunuzda ve dosya adında birden çok dosya olabilir. Bu, benim durumumdaki kullanıcı tarafından yüklenen fotoğraflar gibi.
Rauli Rajande

2
Dosya adının uzantısı yoksa bu başarısız olur. "Dosyam" ı geçmeyi deneyin, "dosyam" dönecektir. Doğru dönüş değeri, bu kullanım durumunda uzantı olarak boş bir dizedir.
pmont

Bu, array_pop () öğesinin parametre olarak bir işaretçi alması nedeniyle bir bildirim atacağında yanlıştır.
jurchiks

12

1) Eğer kullanıyorsanız (PHP 5> = 5.3.6) kullanabilirsiniz SplFileInfo :: getExtension - dosya uzantısını alır

Örnek kod

<?php

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

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

?>

Bu çıktı

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

2) (PHP 4> = 4.0.3, PHP 5) kullanıyorsanız uzantıyı almanın başka bir yolu da pathinfo

Örnek kod

<?php

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

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

?>

Bu çıktı

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

// DÜZENLE: köşeli ayraç kaldırıldı


12

Bazen kullanmamak yararlıdır pathinfo($path, PATHINFO_EXTENSION). Örneğin:

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

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

Ayrıca, pathinfobazı ASCII olmayan karakterleri işleyemediğini unutmayın (genellikle bunları çıkıştan bastırır). Genellikle sorun olmayan uzantılarda, ancak bu uyarıdan haberdar olmak acıtmaz.


6
@ e-satis: Wikipedia'ya göre bunlar iki uzantıdır: UNIX benzeri dosya sistemleri, ayrılmış uzantı meta verileri olmadan farklı bir model kullanır. Nokta karakteri, ana dosya adındaki başka bir karakterdir ve dosya adları, genellikle files.tar.gz gibi iç içe dönüşümleri temsil eden birden çok uzantıya sahip olabilir .
Alix Axel

1
Ve ürün adında nokta varsa? Örn:test.19-02-2014.jpeg
Mario Radomanana

/Root/my.folder/my.css ltrim(strrchr($PATH, '.'),'.'), pathinfo gibi çalışır, ancak her şeyi tokenleştirmeden başarısız olur .
Ray Foss

8

PHP'de dosya uzantısı almanın en basit yolu PHP'nin yerleşik işlev pathinfo'sunu kullanmaktır .

$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

Bunu da deneyebilirsiniz (PHP 5. * ve 7'de çalışır):

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

İpucu: dosyanın bir uzantısı yoksa boş bir dize döndürür


7

Üzgünüm ... "Kısa Soru; Kısa Cevap DEĞİL"

PATH için örnek 1

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

URL için örnek 2

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

Örnek 1'in çıktısı:

Name: base.min
Extension: css

Örnek 2'nin çıktısı:

Name: file.bak
Extension: php

Referanslar

  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

Hızlı bir düzeltme böyle bir şey olacaktır.

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

Neden sadece uzun kod kullanmak yerine php.net/manual/en/function.pathinfo.php amacı için fonksiyon inşa yerleşik php kullanmak değil
Shahbaz

1
Şahbaz'ın yanı sıra $file_ext = end(explode('.', $filename));bu cevaptaki her şeyi dört yerine tek bir satırda da yapabilirsiniz.
tvanc

@Amelia Ya sahipsen .tar.gz. Bu işe yaramayacaktır, bu nedenle yanlış bir şekilde tam uzantı ltrim(strstr($filename, '.'), '.');almak gibi uzatma dolu almak gerekiyorsa gz.
Marin Sagovac

6

İşte bir örnek. $ Dosya adının "example.txt" olduğunu varsayalım,

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

Yani $ ext ".txt" olacaktır.


6

pathinfo bir dizidir. Dizin adını, dosya adını, uzantısını vb. Kontrol edebiliriz :

$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
Bu /root/my.folder/my.css
Ray Foss ile

1
Bu düzgün çalışmalıdır: substr ($ path, strrpos ($ path, '.') + 1); Not: Bu yöntem yukarıdaki diğer çözümlerden daha hızlıdır. Kendi senaryomuzu kullanarak bir kıyaslama deneyin.
Abbas

4

Bunu da deneyebilirsiniz:

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

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

name.name.name.ext (çirkin, ancak bazen olur) gibi dosya adlarınız varsa bu en iyi yoldur



3

pathinfo()Ve SplFileInfoçözümlerinin yerel dosya sistemindeki standart dosyalar için iyi çalıştığını buldum , ancak geçerli resimler için URL'ler bir #(parça tanımlayıcıları) ve / veya ?(sorgu parametreleri) olabileceğinden uzak dosyalarla çalışıyorsanız zorluklarla karşılaşabilirsiniz. URL'nin sonunda, bu çözümlerin her ikisi de (yanlış) dosya uzantısının bir parçası olarak ele alınır.

Bunun, pathinfo()URL'den dosya uzantısından sonra gereksiz dağınıklığı gidermek için ayrıştırdıktan sonra kullanmak için güvenilir bir yol olduğunu gördüm :

$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

Kullanın substr($path, strrpos($path,'.')+1);. Tüm karşılaştırmaların en hızlı yöntemidir.

@Kurt Zhong zaten cevapladı.

Burada karşılaştırmalı sonucu kontrol edelim: https://eval.in/661574


2

Belirli bir klasördeki tüm dosya uzantılarını alabilir ve belirli bir dosya uzantısıyla işlemler yapabilirsiniz:

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

Daha hızlı yap.

Düşük seviyeli çağrıların çok hızlı olması gerekiyor, bu yüzden biraz araştırmaya değer olduğunu düşündüm. Birkaç yöntem denedim (çeşitli dize uzunlukları, uzatma uzunlukları, her biri birden çok çalışır), burada bazı makul olanlar:

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

Sonuçlar çok şaşırtıcı değildi. Zavallı (açık farkla pathinfo!) En yavaş (her şeyi ayrıştırmaya ve sonra tüm gereksiz parçaları düşürmeye çalışıyor gibi görünüyor) - ve method3()(strrpos) en hızlısıdır:

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

NOT: ilk yöntemin bir yan etkisi vardır: uzantı olmadığında tüm adı döndürür. Elbette bu davranışı önlemek için ek bir strpos ile ölçmek mantıklı olmaz.

Sonuç

Samurayın Yolu gibi görünüyor:

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

1

Hız (bir yönlendirici gibi) arıyorsanız, muhtemelen her şeyi belirtmek istemezsiniz. Diğer birçok cevap başarısız olacak/root/my.folder/my.css

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

1

"En iyi yol" tartışmalı olsa da, bunun birkaç nedenden dolayı en iyi yol olduğuna inanıyorum:

function getExt($path)
{
    $basename = basename($path);
    return substr($basename, strlen(explode('.', $basename)[0]) + 1);
}
  1. Bir uzantıya birden fazla parça ile çalışır, ör. tar.gz
  2. Kısa ve etkin kod
  3. Hem dosya adı hem de tam yol ile çalışır

1

IMO, name.name.name.ext (çirkin, ancak bazen olur) gibi dosya adlarınız varsa, bu en iyi yoldur:

$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 yaklaşımında düzenli ifade arama ve değiştirme kullanıyoruz. Preg_replace işlevinde ilk parametre arama için örüntüdür, ikinci parametre $ 1, birinci (. *) İle eşleşen her şeye bir referanstır ve üçüncü parametre dosya adıdır.

Başka bir yol da, bir '.' bir dosya adında ve dizeyi (.) 'den patlayacak şekilde 1 artırın

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


0

Aslında bunu arıyordum.

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

kullanım

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

hızlı bir uzantı alımı için (dosya adınızın bir tane olduğundan eminseniz).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.