编码问题导致同一目录下创建两个同名文件夹的问题求助
问题原因
- 核心触发点为Unicode字符串的规范化形式差异:Unicode定义了多种等价编码表示形式,常用的包括NFC(规范化合成形式)和NFD(规范化分解形式),两种形式的字符视觉表现完全一致,但底层字节编码完全不同。
- 不同客户端的默认编码规范不一致:Windows系统、普通浏览器默认使用NFC格式编码字符串,而iOS、macOS系统默认使用NFD格式编码字符串。你分别从Windows Postman和macOS Postman发起请求时,传入的
name参数看起来文字相同,实际传到PHP后端的字节序列存在差异,因此PHP判断文件夹不存在,触发重复创建逻辑。 - 当前PHP代码没有做编码统一处理,直接用原始输入的字符串作为文件夹名称,最终出现“同名”文件夹重复创建的问题。
解决方案
- 方案1:统一对输入的文件夹名称做编码规范化处理
PHP可以直接用normalizer_normalize()函数将所有输入的字符串统一转为同一种规范化形式,推荐统一转NFC格式,代码示例:
// 先对输入的名称做统一规范化处理 $rawName = $_POST["name"]; $name = normalizer_normalize($rawName, Normalizer::FORM_C); // 统一转为NFC格式
注意:如果你的PHP环境没有开启intl扩展,需要先在php.ini中开启
extension=intl,重启服务后函数才能正常使用。
同时所有读取文件名做判断的逻辑,也需要做同样的规范化处理,保证判断逻辑一致。
- 方案2:编码转换规避编码差异问题
如果业务允许,也可以对文件名做URL编码或者base64编码后再作为实际存储的文件夹名称,从根源上避免编码差异、特殊字符导致的文件系统兼容性问题,示例:
$name = $_POST["name"]; // 编码后作为文件夹名,完全避免编码差异问题 $safeDirName = base64_encode($name); // 业务层展示原始文件名时,可以关联存储原始文件名到数据库做映射
内容的提问来源于stack exchange,提问作者113408
相关产品推荐
相关产品推荐

