basename:從路徑字串提取檔案名稱的標準函數
basename() 回傳路徑字串中的檔案名稱部分。它不檢查檔案是否存在,純粹進行字串操作,支援 Windows(\ 和 /)與 Unix(/)路徑分隔符。
函數語法
basename(string $path, string $suffix = ""): string
參數說明
| 參數 |
說明 |
$path |
路徑字串 |
$suffix |
可選。若檔案名以此結尾,將被移除(常用於移除副檔名) |
基本範例
<?php
$path = '/home/user/documents/report.pdf';
echo basename($path); // report.pdf
echo basename($path, '.pdf'); // report
echo basename($path, '.doc'); // report.pdf(不匹配,不移除)
// Windows 路徑
$winPath = 'C:\Users\John\Documents\file.txt';
echo basename($winPath); // file.txt
echo basename($winPath, '.txt'); // file
?>
進階應用場景
1. 處理上傳檔案名稱
<?php
$originalName = $_FILES['avatar']['name']; // 可能包含路徑(舊瀏覽器)
$safeName = basename($originalName); // 只取檔名部分
$ext = pathinfo($safeName, PATHINFO_EXTENSION);
$newName = bin2hex(random_bytes(8)) . '.' . $ext;
?>
2. 批次處理檔案
<?php
$files = glob('/var/www/uploads/*.jpg');
foreach ($files as $file) {
$name = basename($file);
$nameWithoutExt = basename($file, '.jpg');
// 處理...
}
?>
3. URL 路徑處理(注意查詢字串)
<?php
$url = 'https://example.com/path/to/file.php?id=123';
echo basename($url); // file.php?id=123 ← 包含查詢字串!
// 正確處理:先解析 URL
$parsed = parse_url($url);
echo basename($parsed['path']); // file.php ✓
?>
4. 移除多種副檔名
<?php
function removeExtension(string $filename): string {
$extensions = ['.php', '.html', '.htm', '.twig', '.blade.php'];
foreach ($extensions as $ext) {
$result = basename($filename, $ext);
if ($result !== $filename) return $result;
}
return $filename;
}
echo removeExtension('view.blade.php'); // view
echo removeExtension('page.html'); // page
?>
常見陷阱
| 問題 |
原因 |
解決 |
| 輸出為空字串 | 路徑以分隔符結尾(如 /home/user/) | 先用 rtrim($path, '/\\') 移除尾部分隔符 |
| 副檔名未移除 | suffix 不匹配(大小寫、多餘點號) | 用 pathinfo() 或 strtolower() 正規化 |
| URL 含查詢字串 | basename 不解析 URL | 先用 parse_url() 取 path |
| 多位元組字元亂碼 | 舊版 PHP + mbstring 設定問題 | PHP 7.2+ 正常,確保檔案編碼 UTF-8 |
basename vs pathinfo vs SplFileInfo
| 需求 |
推薦函數 |
| 只需檔名(含副檔名) | basename($path) |
| 檔名不含副檔名 | basename($path, '.ext') 或 pathinfo($path, PATHINFO_FILENAME) |
| 需多種路徑資訊 | pathinfo($path) 回傳陣列 |
| 物件導向、需檔案屬性 | new SplFileInfo($path)->getFilename() |
pathinfo 完整範例
<?php
$path = '/home/user/docs/report.final.pdf';
$info = pathinfo($path);
/*
Array
(
[dirname] => /home/user/docs
[basename] => report.final.pdf
[extension] => pdf
[filename] => report.final ← 不含副檔名的檔名
)
*/
echo $info['filename']; // report.final
?>
最佳實務
- 處理使用者上傳檔名時,必須用 basename() 移除潛在路徑
- 移除副檔名優先用
pathinfo($path, PATHINFO_FILENAME)(更可靠)
- URL 路徑先
parse_url() 再 basename()
- 跨平台路徑用
DIRECTORY_SEPARATOR 或統一正規化為 /
- 新代碼考慮用
SplFileInfo 物件導向介面
basename 是路徑字串處理的基礎工具,掌握其行為邊界(尾部分隔符、URL、副檔名移除),能避免許多檔案上傳、路徑解析的潛在 Bug。