Do it faster!
In other words, please stop using pathinfo for this job. It's rather slow. Such low-level calls need to be very fast so I thought it was worth some research.
I tried a few methods (with various string lengths, extension lengths, multiple runs each), here's some reasonable ones. I had to update the previous stats because php versions (and kernels and lots of other things) change, but on Linux servers, the takeaway is always the same.
/* 387 ns */ function method1($s) {return preg_replace("/.*\./","",$s);} // edge case problem
/* 769 ns */ function method2($s) {preg_match("/\.([^\.]+)$/",$s,$a);return $a[1];}
/* 67 ns */ function method3($s) {$n = strrpos($s,"."); if($n===false) return "";return substr($s,$n+1);}
/* 175 ns */ function method4($s) {$a = explode(".",$s);$n = count($a); if($n==1) return "";return $a[$n-1];}
/* 731 ns */ function method5($s) {return pathinfo($s, PATHINFO_EXTENSION);}
/* 732 ns */ function method6($s) {return (new SplFileInfo($s))->getExtension();}
Test string was "something.that.contains.dots.txt"; as you see, measurements were divided back to nanoseconds. SplFileInfo
and pathinfo
are great fellas, but for this kind of job it's simply not worth it to wake them up. For the same reason, explode()
is cnosiderably faster than regex. Very simple tools almost always beat more sophisticated ones.
Side note: on Windows, results are totally different. I guess it's worth to run the numbers for your own case if you're using IIS.
Conclusion
This seems to be the Way of the Samurai:
function fileExtension($s) {
$n = strrpos($s,".");
return ($n===false) ? "" : substr($s,$n+1);
}
Some test cases
File name fileExtension()
----------------------------------------
file ""
file. ""
file.txt "txt"
file.txt.bin "bin"
file.txt.whatever "whatever"
.htaccess "htaccess"
(The last one is a bit special; it could be only an extension, or an empty extension with the pure name being ".htaccess", I'm not sure if there's a rule for that. So I guess you can go with both, as long as you know what you're doing.)
strrchr($filename, '.');
– verybadbug