Mach es schneller.
Low-Level-Anrufe müssen sehr schnell sein, daher dachte ich, dass es einige Nachforschungen wert ist. Ich habe einige Methoden ausprobiert (mit verschiedenen Stringlängen, Erweiterungslängen, jeweils mehreren Läufen). Hier sind einige vernünftige:
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);}
Die Ergebnisse
waren nicht sehr überraschend. Schlecht pathinfo
ist (bei weitem!) method3()
Am langsamsten (es sieht so aus, als würde er versuchen, das Ganze zu analysieren und dann alle unnötigen Teile fallen zu lassen) - und (strrpos) ist bei weitem am schnellsten:
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
HINWEIS: Die erste Methode hat einen Nebeneffekt: Sie gibt den gesamten Namen zurück, wenn keine Erweiterung vorhanden ist. Sicherlich würde es keinen Sinn machen, es mit einem zusätzlichen Strpos zu messen, um dieses Verhalten zu vermeiden.
Fazit
Das sieht aus wie der Weg der Samurai:
function fileExtension($s) {
$n = strrpos($s,".");
return ($n===false) ? "" : substr($s,$n+1);
}