From: http://liaosankai.pixnet.net/blog/post/27533126-php-%E5%8F%96%E5%BE%97%E6%AA%94%E6%A1%88%E7%9A%84%E5%89%AF%E6%AA%94%E5%90%8D%28php-get-file-extension%29
--------------------------------------------------------------------------
忘了什麼時候,我意外的連到國外有一篇文章在談論『PHP取得檔案的副檔名(PHP Get File Extension)』的文章。和我之前的前舊文章「取得檔案的副檔名」相比,那位筆者Cowburn顯然比我認真多了。
Cowburn 把所有取得副檔名的方法都找出來了,而且還評論了哪種方法最適合。果然國外的人寫文章,不會只給答案,還會給過程,看來我寫文章也應該好好學著才行。我先 列出Cowburn提到的五種方法,並把其中的註解中文化了。下列的所有方式,最後回傳的結果都是"git"字串,沒有 . 喔!
01.
//假設檔名
02.
$filename
=
'mypic.gif'
;
03.
04.
// 1. 使用陣列函式 "explode/end" 方式
05.
$ext
=
end
(
explode
(
'.'
,
$filename
));
06.
07.
// 2. 使用字串函式 "strrchr" 方式
08.
$ext
=
substr
(
strrchr
(
$filename
,
'.'
), 1);
09.
10.
// 3. 使用字串函式 "strrpos" 方式
11.
$ext
=
substr
(
$filename
,
strrpos
(
$filename
,
'.'
) + 1);
12.
13.
// 4. 使用正規式 "preg_replace" 方式
14.
$ext
= preg_replace(
'/^.*\.([^.]+)$/D'
,
'$1'
,
$filename
);
15.
16.
// 5. 特別(從來沒用過)方式
18.
$exts
= split(
"[/\\.]"
,
$filename
);
19.
$n
=
count
(
$exts
)-1;
20.
$ext
=
$exts
[
$n
];
筆者自己使用的方式,是上面的第一種陣列函式,但是使用array_pop()而不是end(),感覺他的用end()似乎更合適。第二、三種字串 函式取得法,在其它地方看過別人用過。第四種的正規式…我只能說其實這樣算強了,為了取尾檔名,光想那個正規式就傷我腦了,不過正常來講正規式都滿花費效 能的。第五種Cowburn說他從來沒看過,嗯…我也從來沒看過,的確滿特別的。接下來就是Cowburn測試每種的效能,不過他並未將第五種加入比較。 以下是各種方式的速度排序由上(快)而下(慢)
- 第二種:使用字串函式 "strrchr" 方式
- 第三種:使用字串函式 "strrpos" 方式
- 第四種:使用正規式 "preg_replace" 方式
- 第一種:使用陣列函式 "explode/end" 方式
讓我比較意外的是,使用陣列的方式,效能竟然比正規表達式還要差,囧rz,看來我一開始寫的方式,就是最不好的了。不過在排名上第一位的strrchr的方式還不是最好的,好酒沈甕低!Cowburn首選推薦則是使用pathinfo()這個內建函式
1.
$filename
=
'mypic.gif'
;
2.
$ext
=
pathinfo
(
$filename
, PATHINFO_EXTENSION);
原來官方的內建函式pathinfo(),只要再多給第二參數,就能直接取得所需資料,而且這個方式是全部效能上最好的一個,果然是個好辦法。pathinfo第二參考可傳入的值有:
- PATHINFO_DIRNAME:取得資料夾路徑
- PATHINFO_BASENAME:取得整個檔名(主+副)
- PATHINFO_EXTENSION:取得副檔名
- PATHINFO_FILENAME :取得主檔名
我們再來補個官方範例會更清楚一點
01.
$path_parts
=
pathinfo
(
'/www/htdocs/inc/lib.inc.php'
);
02.
03.
echo
$path_parts
[
'dirname'
],
"\n"
;
04.
echo
$path_parts
[
'basename'
],
"\n"
;
05.
echo
$path_parts
[
'extension'
],
"\n"
;
06.
echo
$path_parts
[
'filename'
],
"\n"
;
//從PHP 5.2.0開始有
07.
08.
//上面也可以寫這樣
09.
$path
=
'/www/htdocs/inc/lib.inc.php'
;
10.
11.
echo
pathinfo
(
$path
, PATHINFO_DIRNAME),
"\n"
;
//return '/www/htdocs/inc'
12.
echo
pathinfo
(
$path
, PATHINFO_BASENAME),
"\n"
;
//return 'lib.inc.php'
13.
echo
pathinfo
(
$path
, PATHINFO_EXTENSION),
"\n"
;
//return 'php'
14.
echo
pathinfo
(
$path
, PATHINFO_FILENAME ),
"\n"
;
//return 'lib.inc' (從PHP 5.2.0開始有)
Cowburn 最後總結,就是建議大家使用pathinfo來取得副檔名,看來以後應該沒什麼異議才對。筆者這邊有一個小插曲,有關於 PATHINFO_FILENAME這個在5.2.0推出的新參數。我試著去看他能不能抓到中文檔名,測試結果似乎也是可行的,像是「啦豬賽.png」, 但我不小心用到這個字「菊」,像是「菊花開.png」,就會出問題,抓不到(文件已UTF-8編碼過)。原本猜想是不是此函式內部處理是使用ASCII編 碼,所以我試著先將字串再轉回為Big5, iconv('UTF-8','Big5',$path),再進行擷取,但是卻變成全亂碼了。所以如果有使用PATHINFO_FILENAME 來抓取主檔案名,還是必需注意一下。