Comment obtenir une extension de fichier en PHP?


723

C'est une question que vous pouvez lire partout sur le web avec différentes réponses:

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

Cependant, il y a toujours "la meilleure façon" et cela devrait être sur Stack Overflow.



5
Une autre façon d'obtenir un ext eststrrchr($filename, '.');
verybadbug

Réponses:


1776

Les gens d'autres langages de script pensent toujours que le leur est meilleur car ils ont une fonction intégrée pour faire ça et pas PHP (je regarde Pythonistas en ce moment :-)).

En fait, il existe, mais peu de gens le savent. Rencontrez pathinfo():

$ext = pathinfo($filename, PATHINFO_EXTENSION);

C'est rapide et intégré. pathinfo()peut vous donner d'autres informations, telles que le chemin canonique, selon la constante que vous lui passez.

N'oubliez pas que si vous voulez pouvoir traiter des caractères non ASCII, vous devez d'abord définir les paramètres régionaux. PAR EXEMPLE:

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

Notez également que cela ne prend pas en compte le contenu du fichier ou le type MIME, vous obtenez uniquement l'extension. Mais c'est ce que vous avez demandé.

Enfin, notez que cela ne fonctionne que pour un chemin de fichier, pas un chemin de ressources URL, qui est couvert à l'aide de PARSE_URL.

Prendre plaisir


62
J'aimerais pouvoir voter deux fois. Je ne peux pas vous dire combien de code j'ai pu remplacer en utilisant pathinfo
Mark Biek

8
Moi aussi. C'est pourquoi je le mets ici!
e-satis

7
Whaddaya sait, il s'avère qu'il existe une meilleure façon.
Ben

19
@khizaransari Vous devriez chercher un autre hébergeur, celui que vous avez est stupide. Vraiment, je le pense. Il n'y a aucune raison de désactiver cette fonction. Dites-leur cela. Comme solution de contournement: function get_ext($fname){ return substr($fname, strrpos($fname, ".") + 1); }assurez-vous que le fichier a une extension, il peut faire n'importe quoi lorsque vous passez un chemin en argument!
Luc

12
mon idée de PHP par rapport à python a complètement changé maintenant que je connais cette fonction: O
Tommaso Barbugli

166

pathinfo()

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

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

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

1
Cela fonctionne même à ce niveau (Twitter json): $ ext = pathinfo ($ result-> extended_entities-> media [0] -> video_info-> variants [1] -> url, PATHINFO_EXTENSION);
KJS

101

Exemple d'URL: http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ

A) N'utilisez pas les suggestions d'insécuritéPATHINFO :

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) Utilisez 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: Voir tous les exemples PHP natifs


3
Cette réponse couvre tout, par exemple. un fichier comme foo_folder/foo-file.jpg?1345838509échouera lamentablement avec juste pathinfo,

1
Pas complètement sur le sujet, mais cela a certainement résolu mon problème!
Howie

7
N'oubliez rien! parse_urlest pour l'URL et pathinfopour le chemin du fichier.
Nabi KAZ

1
Que voulez-vous dire "oublier les informations de chemin"? Vous l'utilisez dans la solution!
Automne Leonard

1
@AutumnLeonard Il ne le fait pas, il vient de montrer les différences entre pathinfo et parse_url.

59

Il y a aussi SplFileInfo:

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

Souvent, vous pouvez écrire un meilleur code si vous passez un tel objet au lieu d'une chaîne. Votre code est plus parlant alors. Depuis PHP 5.4, il s'agit d'une ligne unique:

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

Fantastique, ses objets jusqu'en bas :)
Christopher Chase

2
Veuillez ->getExtension()noter qu'il est disponible dans SplFileInfo depuis PHP 5.3.6.
matthias

1
@matthias: Veuillez noter que SPL peut être désactivé dans les versions PHP antérieures à la version PHP 5.3.0. Si vous n'utilisez toujours pas PHP 5.3 mais 5.2 ou inférieur, cette réponse ne convient probablement pas au code stable. Sinon, vous pouvez stabiliser votre code en exigeant une version PHP spécifique et autrement renflouer.
hakre

@hakre Bien que vous ayez raison de dire que "peut être désactivé dans les versions antérieures à 5.3.0", l'extension SPL est néanmoins compilée par défaut à partir de PHP 5.0.0. Ce commentaire a donc un sens pour les personnes obligées d'utiliser PHP 5.2 ou inférieur et qui ne veulent pas démissionner en utilisant des classes SPL spécifiques.
matthias

ouais, juste la version morte duvet :)
hakre

23

La réponse d'E-satis est la bonne façon de déterminer l'extension du fichier.

Alternativement, au lieu de compter sur une extension de fichiers, vous pouvez utiliser le fileinfo pour déterminer le type MIME des fichiers.

Voici un exemple simplifié de traitement d'une image téléchargée par un utilisateur:

// 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
Ceci est la SEULE bonne réponse. Je ne comprends pas pourquoi les gens ont voté pour les autres. Oui, cette approche nécessite plus d'efforts de la part du développeur mais elle augmente les performances (bien que peu, mais c'est le cas). Veuillez vous référer à ceci .
Bhavik Shah

2
@Bhavik: Dans certains cas, nous n'avons besoin que de l'extension de fichier, ils concernent la vérification du type MIME. Mais la vraie question concerne l'extension du fichier, pas le type de fichier. Ce n'est donc PAS la meilleure réponse à cette question. (encore une réponse)
Sasi varna kumar

ce commutateur a besoin d'une parenthèse supplémentaire
rsb2097

16

Tant qu'il ne contient pas de chemin, vous pouvez également utiliser:

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

$fnameest un nom du fichier, par exemple: my_picture.jpg. Et le résultat serait:jpg


@Pourquoi cela a-t-il 3 downvotes? son résultat correct. Veuillez expliquer
railsbox

Ce n'est pas faux, ce n'est tout simplement pas la meilleure façon de le faire. Surévalué pour un peu d'équilibre.

C'est le meilleur moyen, lorsque vous avez besoin de l'extension réelle et que le nom de fichier peut contenir plusieurs., Comme les photos téléchargées par l'utilisateur dans mon cas.
Rauli Rajande

2
Cela échoue si le nom de fichier n'a pas d'extension. Essayez de passer "monfichier" et il renverra "monfichier". La valeur de retour correcte est une chaîne vide comme extension dans ce cas d'utilisation.
pmont

C'est faux dans la mesure où array_pop () enverra un avis car il prend un pointeur comme paramètre.
jurchiks

12

1) Si vous utilisez (PHP 5> = 5.3.6), vous pouvez utiliser SplFileInfo :: getExtension - Obtient l'extension de fichier

Exemple de code

<?php

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

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

?>

Cela produira

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

2) Une autre façon d'obtenir l'extension si vous utilisez (PHP 4> = 4.0.3, PHP 5) est pathinfo

Exemple de code

<?php

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

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

?>

Cela produira

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

// EDIT: suppression d'un crochet


12

Parfois, il est utile de ne pas l'utiliser pathinfo($path, PATHINFO_EXTENSION). Par exemple:

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

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

Notez également que pathinfone parvient pas à gérer certains caractères non ASCII (généralement il les supprime simplement de la sortie). Dans les extensions, ce n'est généralement pas un problème, mais cela ne fait pas de mal d'être conscient de cette mise en garde.


6
@ e-satis: Selon Wikipedia, il s'agit de deux extensions: les systèmes de fichiers de type UNIX utilisent un modèle différent sans les métadonnées d'extension séparées. Le caractère point n'est qu'un autre caractère du nom de fichier principal et les noms de fichiers peuvent avoir plusieurs extensions, représentant généralement des transformations imbriquées, telles que files.tar.gz .
Alix Axel

1
Et si nous avons un point dans le nom du produit? Ex:test.19-02-2014.jpeg
Mario Radomanana

Cela échouera avec /root/my.folder/my.css ltrim(strrchr($PATH, '.'),'.')fonctionne comme pathinfo, mais sans tout tokeniser.
Ray Foss

8

La façon la plus simple d'obtenir une extension de fichier en PHP consiste à utiliser la fonction intégrée PHP de 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

Vous pouvez également essayer ceci (cela fonctionne sur PHP 5. * et 7):

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

Astuce: il renvoie une chaîne vide si le fichier n'a pas d'extension


7

Désolé ... "Question courte; mais PAS réponse courte"

Exemple 1 pour 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);

Exemple 2 pour 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);

Sortie de l'exemple 1:

Name: base.min
Extension: css

Sortie de l'exemple 2:

Name: file.bak
Extension: php

Références

  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

Une solution rapide serait quelque chose comme ça.

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

Pourquoi ne pas simplement utiliser la fonction intégrée de php dans le but php.net/manual/en/function.pathinfo.php au lieu d'utiliser du code long
Shahbaz

1
Outre le point de Shahbaz, vous pouvez également $file_ext = end(explode('.', $filename));faire tout ce qui est dans cette réponse sur une seule ligne au lieu de quatre.
tvanc

@Amelia Et si vous en avez .tar.gz. Cela ne fonctionnera pas, donc si vous avez besoin d'une extension complète, utilisez par exemple ltrim(strstr($filename, '.'), '.');pour obtenir une extension complète à la place de manière incorrecte gz.
Marin Sagovac

6

Voici un exemple. Supposons que $ filename soit "example.txt",

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

Donc $ ext sera ".txt".


6

pathinfo est un tableau. Nous pouvons vérifier le nom du répertoire, le nom du fichier, l'extension , 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
Cela échouera avec /root/my.folder/my.css
Ray Foss

1
Cela doit fonctionner correctement: substr ($ path, strrpos ($ path, '.') + 1); Remarque: cette méthode est plus rapide que toutes les autres solutions ci-dessus. Essayez une référence en utilisant notre propre script.
Abbas

4

Vous pouvez également essayer ceci:

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

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

c'est le meilleur moyen si vous avez des noms de fichiers comme name.name.name.ext (laid, mais cela arrive parfois



3

J'ai trouvé que les solutions pathinfo()et SplFileInfofonctionnent bien pour les fichiers standard sur le système de fichiers local, mais vous pouvez rencontrer des difficultés si vous travaillez avec des fichiers distants car les URL des images valides peuvent avoir un #(identificateurs de fragment) et / ou? (paramètres de requête) à la fin de l'URL, que ces deux solutions traiteront (incorrectement) comme faisant partie de l'extension de fichier.

J'ai trouvé que c'était un moyen fiable à utiliser pathinfo()sur une URL après la première analyse pour éliminer l'encombrement inutile après l'extension de fichier:

$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

Utilisez substr($path, strrpos($path,'.')+1);. C'est la méthode la plus rapide de toutes les comparaisons.

@Kurt Zhong a déjà répondu.

Vérifions le résultat comparatif ici: https://eval.in/661574


2

Vous pouvez obtenir toutes les extensions de fichier dans un dossier particulier et effectuer des opérations avec une extension de fichier spécifique:

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

Fais le plus vite.

Les appels de bas niveau doivent être très rapides , j'ai donc pensé que cela valait la peine d'être étudié. J'ai essayé quelques méthodes (avec différentes longueurs de chaîne, longueurs d'extension, plusieurs exécutions chacune), en voici quelques-unes raisonnables:

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

Les résultats n'étaient pas très surprenants. Pauvre pathinfoest (de loin!) Le plus lent (on dirait qu'il essaie d'analyser le tout puis de supprimer toutes les parties inutiles) - et method3()(strrpos) est de loin le plus rapide:

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

REMARQUE: la première méthode a un effet secondaire: elle renvoie le nom complet lorsqu'il n'y a pas d'extension. Cela n'aurait sûrement aucun sens de le mesurer avec un strpos supplémentaire pour éviter ce comportement.

Conclusion

Cela ressemble à la Voie du Samouraï:

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

1

Si vous recherchez la vitesse (comme dans un routeur), vous ne voudrez probablement pas tout symboliser. Beaucoup d'autres réponses échoueront avec/root/my.folder/my.css

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

1

Bien que la "meilleure façon" soit discutable, je pense que c'est la meilleure façon pour plusieurs raisons:

function getExt($path)
{
    $basename = basename($path);
    return substr($basename, strlen(explode('.', $basename)[0]) + 1);
}
  1. Il fonctionne avec plusieurs parties d'une extension, par exemple tar.gz
  2. Code court et efficace
  3. Il fonctionne avec un nom de fichier et un chemin complet

1

OMI, c'est le meilleur moyen si vous avez des noms de fichiers comme name.name.name.ext (moche, mais cela arrive parfois):

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

approche preg_replace nous utilisons la recherche et le remplacement d'expressions régulières. Dans la fonction preg_replace, le premier paramètre est le modèle de la recherche, le deuxième paramètre $ 1 est une référence à tout ce qui correspond au premier (. *) Et le troisième paramètre est le nom du fichier.

Une autre façon, nous pouvons également utiliser strrpos pour trouver la position de la dernière occurrence d'un '.' dans un nom de fichier et incrémentez cette position de 1 afin qu'il explose la chaîne de (.)

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


0

En fait, je cherchais ça.

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

Utilisation

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

pour une récupération rapide de l'extension (si vous savez avec certitude que votre nom de fichier en a un).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.