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