PHP Get File Extension

Over time, I’ve seen a wide range of scripts which for one reason or another have had the need to grab the extension from a file name or path (E.g. “gif” from “mypic.gif”). Oftentimes the solution tends to fall back on what the task appears to need: string manipulation. Though, as you’ll see, this may not be the best approach to take.

To make things a little clearer for people who can visualise code more easily than paragraphs of text, here are a few examples of what I’ve seen used in the past. The samples are mostly compacted onto a single line but if you’re not comfortable with multiple things happening in one line, feel free to expand them into multiple steps. In all cases, $ext ends up being “gif” .

$filename = 'mypic.gif';

// 1. The "explode/end" approach
$ext = end(explode('.', $filename));

// 2. The "strrchr" approach
$ext = substr(strrchr($filename, '.'), 1);

// 3. The "strrpos" approach
$ext = substr($filename, strrpos($filename, '.') + 1);

// 4. The "preg_replace" approach
$ext = preg_replace('/^.*\.([^.]+)$/D', '$1', $filename);

// 5. The "never use this" approach
//   From: http://php.about.com/od/finishedphp1/qt/file_ext_PHP.htm
$exts = split("[/\\.]", $filename);
$n = count($exts)-1;
$ext = $exts[$n];

Forgetting approach number 5 (the “never use this” approach!), they seem fairly reasonable ways of parsing the $filename string and grabbing the extension. So much so that those approaches can be found dotted around the interweb when people ask the question “How to get the file extension in PHP?

Speed, baby, speed!

Because these are commonly used snippets of code, I decided to pitch them against each other and find out which was the most efficient–by that I simply mean the fastest processing–method just to satisfy my curiosity. The exact details of how they were tested I don’t plan to go into in this post, but here is what I found. On order of fastest to slowest were:

  1. strrchr
  2. closely followed by strrpos
  3. then preg_replace
  4. with explode/end coming in almost twice as slow as the str* methods

Great, so the idea is to use the $ext = substr(strrchr($filename, '.'), 1); approach from now on? Hold on there sonny boy, not so fast! There is another contender which has not been considered yet (though some of you would have been screaming his name from the start). Time to introduce the pathinfo function.

“Hello”, says pathinfo.

Pathinfo does a number of things, depending on what we ask of it, but put simply it returns (path) information about a filepath. Full details can be found on the handy dandy pathinfo page in the PHP manual. Explore the PHP manual page when you get time, but for the purpose of this blog post I’ll hone in to one specific use of the function: getting the file extension. In order to do that, we simply call the function passing along the full filename and a ‘flag’ (a constant which dictates the behaviour of the function) asking for the extension only.

$filename = 'mypic.gif';
$ext = pathinfo($filename, PATHINFO_EXTENSION);

That’s all there is to it! In my opinion, this approach ‘reads’ much more easily than the mess of nested function calls and playing around with string positions, regular expressions, etc.. It is concise and to the point: call pathinfo and only give me back the extension. Simple.

Now for the icing on the cake. When pitched against the other methods detailed above, this call to pathinfo beats all of the others into submission. At least in my testing, it is the fastest method of all (though in random hiccups strrchr does win in around 1% of tests) being on average 1/10th faster than even the strrchr approach.

Summary, or “the bit lazy people should read”

So, to cut a long blog post short, the method that I’ll be using to grab the file extension is simply:

$filename = 'mypic.gif';
$ext = pathinfo($filename, PATHINFO_EXTENSION);

What do you currently use? Have you had any problems using pathinfo, any particular quirks or annoyances?

Previous
Next

74 Comments on PHP Get File Extension.

Add your two pennies, others have already donated theirs.

  1. Haris
    Jan 15 2008 at 03:59 BST

    I used the explode() method which was really clean to me. explode() never annoyed me but it was a bit longer since you need to work on the array to print out the extension. (without die, I suppose).

    pathinfo() is really easy as compared to all the other contenders but proper profiling still needs to be done to find the fastest contender in terms of speed. I don’t really care about those 0.00001ms of speed but some do..

  2. Peter
    Jan 16 2008 at 16:04 BST

    I know that someone are very, very interested in scraping away those thousands of milliseconds from their scripts — to a degree it also interests me in a “hmm, lets see what we can do” way rather than a necessity for each and every line of code I ever create.

    Personally, I think that pathinfo(..., PATHINFO_EXTENSION) is by far the easiest code snippet to read and understand quickly what is going on, compared to the other alternatives posted here. :)

  3. scott
    scott
    Jan 27 2008 at 23:55 BST

    Hey. Just dropping a note of appreciation. Nice when someone publishes something that is simple and direct as to the best practice, given the myriad of options available to you in PHP.

    Thanks!

  4. Paul
    Feb 10 2008 at 01:01 BST

    If you are making a file upload script, it is crucial that you use the pathinfo method to finding the true file extension. Because it is possible to fake out php by just renaming the file’s extension. Then when you upload it, if you use explode / strchr method, it will give you the wrong extension.

  5. Peter
    Feb 10 2008 at 20:50 BST

    I’m not sure how providing a file extension which does not match the file content will “fake out” PHP but I do know that whichever of the methods listed above is used, they each produce the same result. If explode / strchr methods give the “wrong” extension, so will pathinfo.

  6. Paul
    Feb 12 2008 at 08:46 BST

    Oh sorry, I was thinking of something else: http://www.jellyandcustard.com/2006/01/19/php-mime-types-and-fileinfo/

    But that’s only really important for file uploads, and I guess you were mainly talking about files that were already on the server. Myyy badd.

  7. Miro
    Miro
    Jul 25 2008 at 16:36 BST

    if you can live with the dot:
    strrchr($name,’.')

    will return “.php”

  8. Miro
    Miro
    Jul 25 2008 at 16:39 BST

    That’s about ~2x faster than pathinfo()

  9. Steve
    Steve
    Sep 5 2008 at 10:47 BST

    Thank you.
    Nice and direct.

  10. Carl
    Carl
    Sep 20 2008 at 19:10 BST

    Beautifully explained. Thanks!

  11. Chuck Hoight
    Chuck Hoight
    Nov 13 2008 at 02:40 BST

    This is a great post, with useful, practical information. Hat’s off to you, sir.

  12. Robin Thomas
    Robin Thomas
    Apr 7 2009 at 03:50 BST

    what about
    $filename = ‘my.pic.gif’;

  13. Peter
    Apr 7 2009 at 09:44 BST

    Robin, pathinfo('my.pic.gif', PATHINFO_EXTENSION) would return gif as expected.

  14. Alex
    Apr 20 2009 at 23:20 BST

    Thanks for this :) There are so many functions in PHP, and I have now discovered a new one :)

  15. Josso
    Josso
    Jun 19 2009 at 21:56 BST

    And what about this:
    $fileinfo = “file.tar.gz”;

    Would it return the proper tar.gz or just the gz?

    Any way to easy do this or do we have to use the explode and check for every filetype? :/

    Cheers,

  16. Peter
    Jun 19 2009 at 22:45 BST

    Thanks for the comment Josso. In that case
    gz

    would be returned as the file extension (which is fine if you see it as a gzipped tar file, and not a “tar gzip” file). It would be easy enough to look for the tar if you needed to for whatever reason.

  17. Corey
    Jul 19 2009 at 02:39 BST

    Josso:

    A file named file.tar.gz is a gzip file, so ‘gz’ is the proper extension. If you gunzip it, you are left with a tarball with a ‘tar’ extension. This is all by design. An alternate extension for a gzipped tarball is .tgz, however it’s more technically valid to have .tar.gz. It does matter when you run into an instance where you want to gunzip without extracting the tarball.

  18. Zach
    Zach
    Oct 2 2009 at 07:43 BST

    Ummm, NO! Do NOT use explode, strchr, substr etc. to parse filenames like this. You will end up with bugs and potential security problems. Why? Well, think about all the different permutations of filenames that can cause problems. This is especially true of user-input strings (like for file uploads, etc.). Use the pathinfo() function.

    Please update your article to reflect this so the monkeys of the world will stop using strchr in their code to parse paths. Thanks.

  19. Peter
    Oct 2 2009 at 09:00 BST

    Would the monkey please take care to actually read the article in its entirety? The advice in the article is indeed to use the pathinfo function and there’s even a “bit lazy people should read” which summarises the post in under 30 words, but thanks for your concern.

  20. strony internetowe
    Oct 3 2009 at 08:22 BST

    Thank you.
    Nice and direct.

  21. Robert Nicklin
    Nov 4 2009 at 22:04 BST

    Great article specifically for the speed testing of the different options listed. Came in handy for a directory listing script I’m working on. Thanks!

  22. Nov 24 2009 at 13:36 BST

    [...] get file extension comparison [...]

  23. Nikhil
    Nikhil
    Dec 7 2009 at 08:40 BST

    i think that the explode method is not a reliable one.B’coz try uploading a file named filename.gif.php, the explode method will return the extension as .gif and it ignores the .php part. its a potentional security flow as any one can uplaod the php file and execute it.

    So i would recommend using the pathinfo function.

  24. Peter
    Dec 7 2009 at 11:54 BST

    So i would recommend using the pathinfo function.

    Absolutely, that’s the entire point of this article. Thanks for commenting. :)

  25. Eric Di Bari
    Jan 20 2010 at 19:26 BST

    Great accurate article. Thanks for condensing the functions into one lines as well, I always try to make my code as concise as possible. Thanks.

  26. Peter
    Jan 20 2010 at 19:40 BST

    Thanks Eric. I too like concise code so long as it’s concise and readable; if the code is just mushed together and obfuscated for the sake of keeping it small, then that’s no so cool. :)

  27. ali
    ali
    Feb 23 2010 at 10:50 BST

    thank you very much
    helpful and direct..
    keep it up!

  28. Keith
    Keith
    Apr 12 2010 at 22:27 BST

    Thank you.

  29. Marcus
    Marcus
    Apr 29 2010 at 13:14 BST

    You need to organize this article better… someone could read the first 2 paragraphs, decide that strrchr never realizing pathinfo is proper!
    pathinfo should be mentioned from the very beginning and listed with all the other options, and it would make way more sense.

  30. Peter
    Apr 29 2010 at 13:40 BST

    Marcus, the particular structure was chosen as a story moving from the bad to the good. For people that cannot be bothered to read and digest the whole article (it’s hardly a monster, nor complicated!) then I cannot be bothered to try and teach them something.

    For those who will actually read an article, the information is all there. I did go to the trouble of adding “the bit lazy people should read” for those who like to scan headings and still numerous people have taken the time to comment that I should have recommended pathinfo. :)

  31. M T Northrop
    M T Northrop
    Jun 1 2010 at 13:31 BST

    Hi Peter,

    Many thanks for this!

    Please ignore the people who didn’t bother to read the whole article and give us more of the same.

    Simple, yet thorough, explanations of PHP best practices are severely lacking on the internet.

    Your RSS feed has just gotten another subscriber…

  32. Peter
    Jun 1 2010 at 14:19 BST

    Thanks Mark, if you have any suggestions on topics to cover they would be more then welcomed.

    P.S. Welcome to the tiny, yet super-special, few who subscribe to here. :)

  33. thiagovidal
    thiagovidal
    Jul 1 2010 at 01:21 BST

    Thanks dude!!! I was trying just like a monkey and getting nothing… A lot of scripts on internet with difficult approach. Your solution came from heaven!!!

    [Ed. Code snippet not using pathinfo() removed.]

  34. bindiya
    bindiya
    Jul 16 2010 at 08:55 BST

    thank you. this helps me a lot.

  35. Alex C
    Alex C
    Sep 3 2010 at 16:35 BST

    Thanks. Very nice selection of options, and the best part — you did a test to find the fastest for us :)

  36. Will
    Sep 24 2010 at 17:27 BST

    Be careful using the first example. split() is deprecated in PHP 5.3.

    Nice blog post though. Thanks!

  37. JeiboyAndroidUpdate
    Nov 22 2010 at 16:55 BST

    Nice code bro. Im looking for this,

  38. staima
    Dec 28 2010 at 19:56 BST

    all methods fail if path has query or hash:
    $filename = “mypic.gif?see=me#now”;

  39. Peter
    Dec 28 2010 at 21:47 BST

    @staima: Just like any other function, if you put rubbish in then you’ll (probably) get rubbish out; File paths don’t have query strings.

  40. Feb 9 2011 at 03:21 BST

    [...] very first result was this: http://cowburn.info/2008/01/13/get-file-extension-comparison/ article by somebody called [...]

  41. VesQ
    VesQ
    Mar 5 2011 at 09:33 BST

    Congratulations on the first google result for search “php get file extension”. I love this simple snippet of code and wouldn’t have found it by just browsing through php-manual on my own.

  42. Luka Peharda
    Mar 24 2011 at 08:31 BST

    Nice blog post. Just what I was looking for.

  43. szr
    Apr 19 2011 at 16:14 BST

    Thanks, for the simple, straightforward post! It was helpful!

  44. Salon
    May 30 2011 at 19:51 BST

    I am looking for these comparison for a while. Many thanks for suggestion the best way to get file extension, This is so easy to use and no complicate. Next time I write code, I will use PATHINFO_EXTENSION ^^

  45. Sandeep
    Sandeep
    May 31 2011 at 13:16 BST

    Very good article. I think the right way to go is pathinfo way. Others are just workaround.

  46. Eric P
    Eric P
    Jun 8 2011 at 11:44 BST

    Great write up/discussion.

    Many times, I want to parse the extension and get the file name (sans the extension) as well. I typically use:

    $ext = substr(strrchr($filename, '.'), 1);
    $file = rtrim($filename, '.'.$ext);

    This method also allows you to define the separator (‘.’ or ‘|’ or ‘str’, etc.) for other types of applications where you are looking to split a string into two parts based on the last defined character (or string/pattern).

  47. Peter
    Jun 8 2011 at 11:54 BST

    Eric, you could also just use pathinfo() as outlined above and basename() functions, to get the extension and file name respectively. Being allowed to use alternative separators makes little sense for file names/extensions, and if you’re working with strings that are not file names then it doesn’t make sense to use file functions. :)

  48. Eric P
    Eric P
    Jun 8 2011 at 12:07 BST

    Peter,

    Okay, I concede, in that this is a “file” and “extension” discussion. :)

    But… it’s semantics! The so called “file” functions have less to do with files, and more to do with string parsing, no?

  49. Peter
    Jun 8 2011 at 12:10 BST

    They are intended for files, if they’re used any other way then that is entirely the developer’s choice. ;)

  50. Jun 26 2011 at 19:07 BST

    [...] recently need to get the file extension from a string. After a quick Google search I found this page which mentions 5 different methods for getting a file extension. While the author does make it [...]

  51. Rohit
    Jul 20 2011 at 02:31 BST

    Thanks for the post. I am glad I found your article because I want the fastest script tempered with readability.

  52. Luneya
    Jul 20 2011 at 08:12 BST

    I liked your article!

    But I have one comment on the double extensions (like image.php.gif):

    .gif will be returned by both of the following lines of code:
    $ext = substr($filename, strrpos($filename, ‘.’) + 1);

    $ext = strrchr($filename, ‘.’);

    I’m not trying to debate which method is best, but I wanted to point out that there are other ways to figure out the last extentension with multiple dots in a filename.

  53. HillbillyGeek
    HillbillyGeek
    Sep 4 2011 at 00:07 BST

    This is why it’s so wonderful that nothing ever goes away on the web. This article was written in 2008, and here we are in the waning days of 2011, and BOOM!
    It helped me.
    I found that the new php was giving me fits about my venerable
    end(explode(‘.’, $filename) method.:

    ( ! ) Strict standards: Only variables should be passed by reference in /Users/xxx.php on line 689

    This was much easier than wrapping my head around the use of & and passing things by reference…

  54. Martin
    Martin
    Nov 4 2011 at 10:14 BST

    Be careful when using pathinfo to get the extension: it returns the case-sensitive extension.
    So a check for $file['extension'] == 'jpg' will return
    false

    when the file is named
    ‘pic.JPG’

    Just use mb_strtolower() on $file['extension'] as a workaround.

  55. Peter
    Nov 4 2011 at 10:22 BST

    Thanks for the comment, Martin. I’d just like to note that pathinfo() doesn’t return “the case-sensitive extension”, it just returns the extension.

    Of course, the file extension may be upper, lower or mixed case but how you deal with that, if at all, is application-specific and not something that pathinfo() should care about. There are several built-in string functions for comparing strings case-insensitively.

  56. Waqas
    Waqas
    Nov 22 2011 at 15:26 BST

    Thanks, it helped me a lot.

  57. Dennis
    Dec 13 2011 at 11:47 BST

    Thanks! My current project will like this :)

  58. Mateusz Michalik
    Dec 15 2011 at 07:45 BST

    Handy tip, thanks!

  59. Anandh
    Jan 12 2012 at 10:55 BST

    Very good concept. Thanks a lot. explode() worked out fine.

  60. Colin
    Colin
    Jan 14 2012 at 22:21 BST

    Big thanks! Nice write up too.

  61. chris at Red Privet
    Jan 19 2012 at 15:43 BST

    Thanks so much for your research. I was able to utilize your findings on a project I’m working on currently.

  62. Casey
    Casey
    Jan 26 2012 at 00:02 BST

    Exactly what I needed. Thank you!

  63. Ram Kishor Agrawal
    Feb 1 2012 at 06:52 BST

    Beautifully explained. Thanks!

  64. Jakob Sternberg
    Feb 4 2012 at 02:57 BST

    The only thing that fails is if the path has a query line attached. Like

    echo pathinfo("http://mysite.com/page.php?file=msg.txt", PATHINFO_EXTENSION)

    - it will output ‘txt’

    Just a note. easy to fix offcourse:

    function getFileExtension($p) {
       if( strpos($p,"?") != '' ) $p = substr($p, 0, strpos($p,"?") );
       return pathinfo($p, PATHINFO_EXTENSION);
       }

    echo getFileExtension("http://mysite.com/page.php?file=msg.txt")

    - will output ‘php’

    Thanks for the heads up on PATHINFO_EXTENSION!

  65. Peter
    Feb 4 2012 at 12:58 BST

    Jacob, this is because pathinfo() works on filesystem paths not URLs. For your example with a URL, you could get the path by using parse_url().

    $path = parse_url($url, PHP_URL_PATH);
    $ext  = pathinfo($path, PATHINFO_EXTENSION);
  66. dan
    dan
    Feb 17 2012 at 17:00 BST

    Hi,

    does the pathinfo() method work with files in the $_FILES array in http post/get?

    being unsure, i’m using the explode way for now.

    thanks for this post, it’s cool.

  67. Peter
    Feb 17 2012 at 18:45 BST

    Dan, yes pathinfo() will work with paths in $_FILES. It just takes a string containing a file path and doesn’t care a jot where it came from.

  68. Eliud
    Eliud
    Mar 11 2012 at 21:35 BST

    Hey, just here to drop a “Thank You!” for showing us this snippet of code. Very simple, but beats the way I was doing it by a mile (r by milliseconds, which is, a lot in terms of a script). Thank you!

  69. publo
    publo
    Mar 19 2012 at 05:53 BST

    yo Peter

    pathinfo() is not secure
    http://www.madirish.net/?article=232

  70. Peter
    Mar 19 2012 at 09:06 BST

    publo, pathinfo() is “secure” in the sense that it does exactly, and only, the job requested of it as documented. If you try to use pathinfo() in a manner other than it is supposed to be used, then it is the developer’s failing. With regards to that article, the developer is simply demonstrating a completely incorrect method for validating the input: pathinfo() is still doing its job correctly. The function is not insecure, the developer trying to use it where it is not appropriate, is.

  71. John doe
    John doe
    Mar 28 2012 at 21:01 BST

    Wow a high level programming discussion, i came…

  72. Peter
    Mar 28 2012 at 21:05 BST

    Mr Doe, happy to be of service. Don’t forget to clean up. ;)

  73. CLiff
    CLiff
    Oct 3 2012 at 07:21 BST

    THANKS!
    My site uploads pictures. Some are .jpeg.
    The programmer went through multi line code to extract .ext and eventually used code that grabbed the last 3 characters; thereby messing up .jpeg files.
    I deleted 4 lines, used pathinfo() and works perfectly.
    Programmer wanted to know where I learned the great code!

    Thank you Peter.
    ps had looked at over 40 articles for extracting .ext.

Post Comment