<?php
echo rtrim('article_list.html', '.html')."\n"; // 預期 article_list 實際 article_list ✓
echo rtrim('article_index.html', '.html')."\n"; // 預期 article_index 實際 article_ind ✗
echo rtrim('articleABCT.html', '.html')."\n"; // 預期 articleABCT 實際 articleABCT ✓
輸出:
article_list
article_ind
articleABCT
rtrim($str, $charlist) 的第二個參數是 字符集合 而非 字符串後綴。函數會從字符串末尾開始,逐個字符檢查是否在字符集合中,若在則刪除,直到遇到不在集合中的字符停止。
'article_index.html' 末尾字符序列:l → m → x → . → l → m → t → h'.html' 包含字符:. h t m lh∈ → 刪,t∈ → 刪,m∈ → 刄,l∈ → 刪,.∈ → 刪,x∉ → 停止。article_ind,ex 被誤刪。function removeExt(string $filename, string $ext): string {
// 確保極性帶點
$ext = $ext[0] === '.' ? $ext : '.' . $ext;
$info = pathinfo($filename);
if (isset($info['extension']) && $info['extension'] === ltrim($ext, '.')) {
return $info['filename']; // 不含擴展名的文件名
}
return $filename; // 擴展名不匹配,原樣返回
}
// 測試
echo removeExt('article_index.html', '.html'); // article_index ✓
echo removeExt('article_index.htm', '.html'); // article_index.htm (不匹配) ✓
function removeSuffix(string $str, string $suffix): string {
if (str_ends_with($str, $suffix)) {
return substr($str, 0, -strlen($suffix));
}
return $str;
}
function removeExtRegex(string $filename, string $ext): string {
$ext = preg_quote($ext, '/');
return preg_replace("/{$ext}$/", '', $filename);
}
| 方法 | 優點 | 缺點 | 適用版本 |
|---|---|---|---|
| pathinfo | 內建、處理路徑分隔符、語義明確 | 需額外判斷擴展名是否匹配 | 所有版本 |
| str_ends_with + substr | 直觀、性能高、嚴格匹配後綴 | PHP 8.0+ | PHP 8.0+ |
| 正則 | 靈活、可處理複雜模式 | 較慢、易寫錯 | 所有版本 |
| rtrim | 代碼短 | 語義錯誤,極易產生 Bug | — |
pathinfo()、basename()、SplFileInfo。str_starts_with/str_ends_with。