Házlo más rápido.
Las llamadas de bajo nivel deben ser muy rápidas, así que pensé que valía la pena investigar un poco. Probé algunos métodos (con varias longitudes de cadena, longitudes de extensión, múltiples ejecuciones cada uno), aquí hay algunos razonables:
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);}
Los resultados
no fueron muy sorprendentes. Pobre pathinfo
es (¡con diferencia!) El más lento (parece que está tratando de analizar todo y luego soltar todas las partes innecesarias), y method3()
(strrpos) es el más rápido, con diferencia:
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: el primer método tiene un efecto secundario: devuelve el nombre completo cuando no hay extensión. Seguramente no tendría sentido medirlo con un strpos adicional para evitar este comportamiento.
Conclusión
Esto se parece al Camino del Samurai:
function fileExtension($s) {
$n = strrpos($s,".");
return ($n===false) ? "" : substr($s,$n+1);
}