Come posso ottenere un'estensione di file in PHP?


723

Questa è una domanda che puoi leggere ovunque sul Web con varie risposte:

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

eccetera.

Tuttavia, c'è sempre "il modo migliore" e dovrebbe essere su Stack Overflow.



5
Un altro modo per ottenere ext èstrrchr($filename, '.');
verybadbug,

Risposte:


1776

Le persone di altri linguaggi di scripting pensano sempre che la loro sia migliore perché hanno una funzione integrata per farlo e non PHP (sto guardando Pythonistas in questo momento :-)).

In realtà, esiste, ma poche persone lo sanno. Incontra pathinfo():

$ext = pathinfo($filename, PATHINFO_EXTENSION);

Questo è veloce e integrato. pathinfo()può darti altre informazioni, come il percorso canonico, a seconda della costante che passi ad essa.

Ricorda che se vuoi essere in grado di gestire caratteri non ASCII, devi prima impostare la locale. PER ESEMPIO:

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

Inoltre, tieni presente che questo non prende in considerazione il contenuto del file o il tipo mime, ottieni solo l'estensione. Ma è quello che hai chiesto.

Infine, nota che questo funziona solo per un percorso di file, non per un percorso di risorse URL, che viene coperto usando PARSE_URL.

Godere


62
Vorrei poterlo votare due volte. Non posso dirvi quanto codice sono stato in grado di sostituire usando pathinfo
Mark Biek,

8
Anche io. Ecco perché l'ho messo qui!
e-satis,

7
Whaddaya lo so, si scopre che c'è un modo migliore.
Ben

19
@khizaransari Dovresti cercare un altro provider di hosting, quello che hai è stupido. Davvero, intendo. Non vi è alcun motivo per disabilitare questa funzione. Diglielo. Per ovviare al problema: function get_ext($fname){ return substr($fname, strrpos($fname, ".") + 1); }assicurati che il file abbia un'estensione, potrebbe fare qualsiasi cosa quando passi un percorso come argomento!
Luc,

12
la mia idea di PHP rispetto a Python è cambiata completamente ora che conosco questa funzione: O
Tommaso Barbugli,

166

pathinfo()

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

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

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

1
Funziona anche a questo livello (Twitter json): $ ext = pathinfo ($ risultato-> extended_entities-> media [0] -> video_info-> varianti [1] -> url, PATHINFO_EXTENSION);
KJS il

101

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

A) Non usare insicuro suggeritoPATHINFO :

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) Utilizzare 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: visualizza tutti gli esempi di PHP nativi


3
Questa risposta copre tutto ad es. un file come foo_folder/foo-file.jpg?1345838509fallirà miseramente con just pathinfo, grazie

1
Non completamente in tema, ma sicuramente ha risolto il mio problema!
Howie,

7
Non dimenticare niente! parse_urlè per URL ed pathinfoè per percorso del file.
Nabi KAZ,

1
Cosa intendi con "dimentica le informazioni sul percorso"? Lo usi nella soluzione!
Autunno Leonard,

1
@AutumnLeonard Non lo fa, ha appena mostrato le differenze tra pathinfo e parse_url.

59

C'è anche SplFileInfo:

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

Spesso puoi scrivere un codice migliore se passi un oggetto del genere invece di una stringa. Il tuo codice parla più allora. A partire da PHP 5.4 questo è un one-liner:

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

Fantastico, i suoi oggetti fino in fondo :)
Christopher Chase,

2
Si noti che ->getExtension()è disponibile in SplFileInfo da PHP 5.3.6.
Matthias,

1
@matthias: tieni presente che SPL può essere disabilitato nelle versioni PHP precedenti alla versione PHP 5.3.0. Se non stai ancora eseguendo PHP 5.3 ma 5.2 o versioni precedenti, molto probabilmente questa risposta non è adatta per il codice stabile. Altrimenti puoi stabilizzare il tuo codice richiedendo una versione specifica di PHP e salvarlo in altro modo.
Hakre,

@hakre Mentre hai ragione nel dire che "può essere disabilitato nelle versioni precedenti alla 5.3.0", l'estensione SPL è comunque compilata di default a partire da PHP 5.0.0. Quindi questo commento ha davvero senso per le persone costrette a usare PHP 5.2 o precedenti e non vogliono dimettersi usando specifiche classi SPL.
Matthias,

sì, solo versione morta lanugine :)
hakre,

23

La risposta di E-satis è il modo corretto di determinare l'estensione del file.

In alternativa, invece di fare affidamento su un'estensione di file, è possibile utilizzare il fileinfo per determinare il tipo MIME dei file.

Ecco un esempio semplificato di elaborazione di un'immagine caricata da un utente:

// 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
Questa è l'UNICA risposta corretta. Non capisco perché la gente abbia votato sugli altri. Sì, questo approccio richiede maggiori sforzi da parte dello sviluppatore ma migliora le prestazioni (anche se poco, ma lo fa). Si prega di fare riferimento a questo .
Bhavik Shah,

2
@Bhavik: in alcuni casi potrebbe essere necessaria solo l'estensione del file, riguardano il controllo del tipo mime. Ma la vera domanda riguarda l'estensione del file, non il tipo di file. Quindi questa NON è la migliore risposta a questa domanda. (ancora una risposta)
Sasi varna kumar,

questo interruttore necessita di una parentesi aggiuntiva
rsb2097,

16

Purché non contenga un percorso, puoi anche utilizzare:

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

Dove $fnameè il nome del file, ad esempio: my_picture.jpg. E il risultato sarebbe:jpg


@Perché questo ha 3 voti negativi? sta dando il giusto risultato. Spiega
railsbox

Non è sbagliato, non è solo il modo migliore per farlo. Ha votato per un po 'di equilibrio.

Questo è il modo migliore, quando hai bisogno della vera estensione e il nome del file può contenere più., Come nel mio caso le foto caricate dall'utente.
Rauli Rajande,

2
Ciò non riesce se il nome file non ha estensione. Prova a passare in "myfile" e restituirà "myfile". Il valore restituito corretto è una stringa vuota come estensione in questo caso d'uso.
pmont,

Questo è errato in quanto array_pop () genererà un avviso perché utilizza un puntatore come parametro.
Jurchiks,

12

1) Se si utilizza (PHP 5> = 5.3.6) è possibile utilizzare SplFileInfo :: getExtension - Ottiene l'estensione del file

Codice di esempio

<?php

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

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

?>

Questo produrrà

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

2) Un altro modo per ottenere l'estensione se si sta utilizzando (PHP 4> = 4.0.3, PHP 5) è pathinfo

Codice di esempio

<?php

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

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

?>

Questo produrrà

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

// EDIT: rimossa una parentesi


12

A volte è utile non usare pathinfo($path, PATHINFO_EXTENSION). Per esempio:

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

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

Si noti inoltre che pathinfonon riesce a gestire alcuni caratteri non ASCII (di solito li elimina dall'output). Nelle estensioni che di solito non è un problema, ma non fa male essere consapevoli di questo avvertimento.


6
@ e-satis: Secondo Wikipedia sono due estensioni: i filesystem simili a UNIX usano un modello diverso senza i metadati di estensione segregati. Il carattere punto è solo un altro carattere nel nome file principale e i nomi file possono avere più estensioni, in genere rappresentano trasformazioni nidificate, come files.tar.gz .
Alix Axel,

1
E se abbiamo un punto nel nome del prodotto? Esempio:test.19-02-2014.jpeg
Mario Radomanana,

Questo fallirà con /root/my.folder/my.css ltrim(strrchr($PATH, '.'),'.')funziona come pathinfo, ma senza tokenizzare tutto.
Ray Foss,

8

Il modo più semplice per ottenere l'estensione di file in PHP è utilizzare la funzione pathinfo integrata di 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

Puoi provare anche questo (funziona su PHP 5. * e 7):

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

Suggerimento: restituisce una stringa vuota se il file non ha estensione


7

Siamo spiacenti ... "Breve domanda; ma NON breve risposta"

Esempio 1 per 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);

Esempio 2 per 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);

Output dell'esempio 1:

Name: base.min
Extension: css

Output dell'esempio 2:

Name: file.bak
Extension: php

Riferimenti

  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 soluzione rapida sarebbe qualcosa di simile.

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

Perché non usare solo la funzione integrata php per lo scopo php.net/manual/en/function.pathinfo.php invece di usare il codice lungo
Shahbaz,

1
Oltre al punto di Shahbaz, puoi anche semplicemente fare $file_ext = end(explode('.', $filename));tutto in questa risposta in una sola riga anziché in quattro.
tvanc,

@Amelia E se lo avessi .tar.gz. Non funzionerà, quindi se è necessario riempire l'estensione utilizzare tale da ltrim(strstr($filename, '.'), '.');riempire l'estensione invece non correttamente come gz.
Marin Sagovac,

6

Ecco un esempio Supponiamo che $ nomefile sia "esempio.txt",

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

Quindi $ ext sarà ".txt".


6

pathinfo è un array. Possiamo controllare il nome della directory, il nome del file, l'estensione , ecc .:

$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
Questo fallirà con /root/my.folder/my.css
Ray Foss

1
Questo deve funzionare correttamente: substr ($ path, strrpos ($ path, '.') + 1); Nota: questo metodo è più veloce di qualsiasi altra soluzione sopra. Prova un benchmark usando il nostro script.
Abbas,

4

Puoi provare anche questo:

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

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

questo è il modo migliore se hai nomi di file come name.name.name.ext (brutto, ma a volte succede



3

Ho scoperto che le soluzioni pathinfo()e SplFileInfofunzionano bene per i file standard sul file system locale, ma è possibile riscontrare difficoltà se si lavora con file remoti poiché gli URL per le immagini valide potrebbero avere un #(identificatori di frammenti) e / o? (parametri di query) alla fine dell'URL, che entrambe queste soluzioni (errate) tratteranno come parte dell'estensione del file.

Ho scoperto che questo era un modo affidabile da utilizzare pathinfo()su un URL dopo averlo analizzato per rimuovere il disordine non necessario dopo l'estensione del file:

$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

Usa substr($path, strrpos($path,'.')+1);. È il metodo più veloce di tutti i confronti.

@Kurt Zhong ha già risposto.

Controlliamo il risultato comparativo qui: https://eval.in/661574


2

Puoi ottenere tutte le estensioni di file in una cartella specifica ed eseguire operazioni con un'estensione di file specifica:

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

Fallo più velocemente.

Le chiamate a basso livello devono essere molto veloci, quindi ho pensato che valesse la pena fare qualche ricerca. Ho provato alcuni metodi (con varie lunghezze di stringa, lunghezze di estensione, più corse ciascuno), eccone alcuni ragionevoli:

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

I risultati non sono stati molto sorprendenti. Povero pathinfoè (di gran lunga!) Il più lento (sembra che stia cercando di analizzare l'intera cosa e quindi rilasciare tutte le parti non necessarie) - e method3()(strrpos) è di gran lunga il più veloce:

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: il primo metodo ha un effetto collaterale: restituisce il nome intero quando non c'è estensione. Sicuramente non avrebbe senso misurarlo con ulteriori strpos per evitare questo comportamento.

Conclusione

Questa sembra la Via del Samurai:

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

1

Se stai cercando velocità (come in un router), probabilmente non vuoi tokenizzare tutto. Molte altre risposte falliranno/root/my.folder/my.css

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

1

Sebbene il "modo migliore" sia discutibile, credo che sia il modo migliore per alcuni motivi:

function getExt($path)
{
    $basename = basename($path);
    return substr($basename, strlen(explode('.', $basename)[0]) + 1);
}
  1. Funziona con più parti in un'estensione, ad es tar.gz
  2. Codice breve ed efficiente
  3. Funziona con un nome file e un percorso completo

1

IMO, questo è il modo migliore se hai nomi di file come name.name.name.ext (brutto, ma a volte succede):

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

approccio preg_replace che usiamo la ricerca e la sostituzione di espressioni regolari. Nella funzione preg_replace il primo parametro è modello per la ricerca, il secondo parametro $ 1 è un riferimento a qualunque cosa corrisponda al primo (. *) E il terzo parametro è il nome del file.

Un altro modo, possiamo anche usare strrpos per trovare la posizione dell'ultima occorrenza di un '.' in un nome file e incrementa tale posizione di 1 in modo che esploda la stringa da (.)

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


0

In realtà, lo stavo cercando.

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

Uso

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

per un rapido recupero dell'estensione (se si è certi che il nome del file ne abbia uno).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.