PHP strtr函数使用数组参数替换文件名字符不生效
问题诱因
替换逻辑不生效有两个直接原因:
strtr是严格大小写敏感的函数,你写的替换映射数组里,键名全是小写u开头的#u00xx格式,但实际文件名里的转义标记是大写U开头的#U00xx,规则完全匹配不上,自然不会执行替换。- 你写的映射表最后一条
"#u00ff" => "ÿ"漏了右侧的闭合双引号,就算修正了大小写问题,全量运行时也会直接触发语法错误。
额外提一句,这个文件名问题的根源是你解压Zip包时,解压工具没有正确识别Zip包内标注的UTF-8文件名编码,把带重音的非ASCII字符转成了#Uxxxx格式的Unicode字面量,不是文件损坏,只是字符没有被正确解析。
修复方法
你不用手写这么长的字符映射表,用正则匹配自动解析转义字符即可,适配所有出现的Unicode字符,不会漏:
public function rename() { $photos = array_diff(scandir(FCPATH . 'images/test' ), ['.', '..']); foreach ($photos as $photo) { // 自动匹配所有#Uxxxx格式的转义标记,转换为对应UTF-8字符 $newFilename = preg_replace_callback('/#U([0-9a-fA-F]{4})/', function($match) { return mb_chr(hexdec($match[1]), 'UTF-8'); }, $photo); // 测试阶段先输出结果确认,确认转换正确后注释掉die即可执行重命名 var_dump($newFilename); // die; rename(FCPATH . 'images/test/' . $photo, FCPATH . 'images/test/' . $newFilename); } }
后续再解压同类Zip包时,直接在服务器执行unzip -O UTF-8 你的压缩包名.zip指定编码解压,从根源避免这类文件名转义问题,不用事后批量修复。
内容的提问来源于stack exchange,提问作者Jolan
相关产品推荐
相关产品推荐

