
本文介绍如何在php中安全截断过长的文件名,同时确保文件扩展名完整保留在截断后的字符串末尾,避免丢失关键类型信息。
本文介绍如何在php中安全截断过长的文件名,同时确保文件扩展名完整保留在截断后的字符串末尾,避免丢失关键类型信息。
在处理用户上传或系统生成的文件名时,常需对显示名称做视觉优化——例如限制总长度以适配UI空间。但若直接使用 mb_strimwidth() 截断整个字符串(如原函数所示),会粗暴截断包括扩展名在内的所有字符,导致类似 resume_t8ffvwnjxibqw... 这样丢失 .pdf 的错误结果。
正确做法是分离文件名与扩展名逻辑:先提取扩展名,再对主文件名部分进行智能截断,最后拼接还原。以下是优化后的实现:
<?php function formatNameFile($nama) {
// 安全提取扩展名(支持多级扩展名如 archive.tar.gz)
$pathInfo = pathinfo($nama);
$extension = $pathInfo['extension'] ?? '';
// 若无扩展名,直接截断原字符串
if (empty($extension)) {
return strlen($nama) > 23 ? mb_strimwidth($nama, 0, 23, '...') : $nama;
}
// 获取不含扩展名的主体(含路径)和纯文件名主体
$filenameWithoutExt = $pathInfo['filename']; // 自 PHP 5.2.0 起可用
// 计算可分配给文件名主体的最大长度(预留“...”+扩展名长度)
$maxNameLength = 23 - strlen($extension) - 3; // “...”占3字符
if ($maxNameLength $maxNameLength
? mb_strimwidth($filenameWithoutExt, 0, $maxNameLength, '...')
: $filenameWithoutExt;
return $truncatedName . '.' . $extension;
}
// 测试用例
echo formatNameFile('resume_t8ffvwnjxibqwhu5l0mk1jwu9mmb4b_3.pdf');
// 输出:resume_t8ffvwnjxibqw...pdf
echo "\n";
echo formatNameFile('document_v2_final_review_revised_v3.docx');
// 输出:document_v2_final_r...docx
echo "\n";
echo formatNameFile('image.png');
// 输出:image.png(未超长,不截断)
echo "\n";
echo formatNameFile('a_very_long_filename_with_no_extension');
// 输出:a_very_long_filename_w...(无扩展名时正常截断)
?>
✅ 关键改进点说明:
- 使用
pathinfo()替代explode('.', $nama),避免误判带点的文件名(如my.photo.jpg或archive.tar.gz); - 动态计算主体截断长度:
23 - strlen($extension) - 3,确保最终字符串 ≤23 字符且完整包含...和扩展名; - 增加边界保护:当扩展名本身超长时优雅降级;
- 兼容无扩展名场景,防止 Notice 错误。
⚠️ 注意事项:
-
mb_strimwidth()依赖mbstring扩展,请确保已启用; - 如需严格保持「显示总长 ≤23」,上述方案已满足;若需「截断后总长恰好为23」,可在拼接后二次校验并微调;
- 前端展示时建议配合 CSS
text-overflow: ellipsis作为备用方案,提升兼容性。
通过结构化解耦与健壮性增强,该函数可安全应用于各类文件管理系统、CMS 后台或云存储界面中。










