Php 使用unicode字符/非UTF重命名文件
好吧,我真的和这件事纠缠了一段时间。 我有数千个错误字符的文件,这些文件是服务器从zip文件中错误提取的,产生了服务器以这种方式转换的名称: 原始文件名(示例)为 现在显示在服务器上的文件的形状为Php 使用unicode字符/非UTF重命名文件,php,unicode,encoding,utf-8,filesystems,Php,Unicode,Encoding,Utf 8,Filesystems,好吧,我真的和这件事纠缠了一段时间。 我有数千个错误字符的文件,这些文件是服务器从zip文件中错误提取的,产生了服务器以这种方式转换的名称: 原始文件名(示例)为 现在显示在服务器上的文件的形状为 QQ#U56fe#U724720160314173435.jpg 在哪里 图 = #U56fe 及 所有文件都有相同的2个字符,但编号不同 我已经尝试了我能想到的任何功能,包括iconvfamily、mb\ufamily、str\u raplace甚至htmlentities\u de/encod
QQ#U56fe#U724720160314173435.jpg
在哪里
图 = #U56fe
及
所有文件都有相同的2个字符,但编号不同
我已经尝试了我能想到的任何功能,包括iconv
family、mb\u
family、str\u raplace
甚至htmlentities\u de/encode>等等。。等等
每种方法要么不起作用,要么会产生其他奇怪的字符
我现在的代码是:
// iconv_set_encoding('input_encoding','GB18030');
// print_r($enc);
if ($handle = opendir('./')) {
while (false !== ($fileName = readdir($handle))) {
$ext = pathinfo($fileName, PATHINFO_EXTENSION);
echo $ext .PHP_EOL;
if ( $ext == 'jpg' ){
echo "========" . mb_detect_encoding($fileName).PHP_EOL . "\r\n";
$newName = mb_convert_encoding($fileName, "UTF-8",mb_detect_encoding($fileName));
// $newName = str_replace("#","\\",$fileName);
// $newName = str_replace("#U56fe",iconv("UTF-8","GB2312","图"),$newName);
// $newName = html_entity_decode($newName,ENT_NOQUOTES,"GB2312");
// $newName = urlencode($newName);
// $newName = urldecode($newName);
//
// Tried //GB2312 // GB18030
// $newName = iconv(mb_detect_encoding($newName, mb_detect_order(), true), "GB18030", $newName);
// echo $newName .PHP_EOL;
// $newName = iconv("UTF-8", "GB18030", $fileName);
// $newName = iconv("GB18030", "UTF-8", $fileName);
// $newName = iconv("ISO-8859-9//TRANSLIT", "UTF-8", $fileName);
// echo $newName .PHP_EOL;
// $newName = mb_convert_encoding($fileName, 'UTF-8', 'HTML-ENTITIES');
// tried both copy and rename+unlink
//rename($fileName, $newName);
copy ($fileName,$newName);
}
}
closedir($handle);
}
我留下了一些失败的尝试,只是为了展示已经尝试过的内容,但实际上我尝试了更多(包括开始时的iconv\u set\u编码)
我在本地(win7/xampp)和实时服务器(centos/Cpanel)上都尝试过该脚本
在经历了这么多的失败之后,我甚至不确定名称是ASCII
、UTF-8
还是UTF-8
中表示的一些unicode
替换
并不是说问题不在于创建新的文件或文件夹——我可以毫无问题地做到这一点。问题是仅使用PHP
重命名现有文件。任何其他重命名方法实际上都有效
奇怪的是,我在另一台本地机器(UBUNTU)上测试了同一个脚本——这台机器运行得很好——当然,这表明某种程度上是OS/PHP设置造成的——但是怎么做呢
而且-必须有某种方法告诉脚本如何使用代码页/编码并动态更改..在GNU/Linux系统上,使用与sh兼容的shell(如bash),您可以获得如下重命名预览:
for f in `find . -type f`; do
g=`echo "$f" | sed -e 's/#U/\\\\u/g'`
h=`/usr/bin/printf "$g"`
if test "$h" != "$f"; then
echo mv "$f" "$h"
fi
done
如果您对建议的重命名感到满意,请通过删除上述语句中的“echo”一词来实际执行重命名:
for f in `find . -type f`; do
g=`echo "$f" | sed -e 's/#U/\\\\u/g'`
h=`/usr/bin/printf "$g"`
if test "$h" != "$f"; then
mv "$f" "$h"
fi
done
要点的可能重复是:PHP假定传递给文件系统函数的字节具有某种编码(可能是您本地的ANSI代码页),如果您的文件名无法在该代码页中编码,那么您就倒霉了。@roland。呵呵..我快要淹死了,而你在描述水:-)。。只是开玩笑。:-。问题是可以理解的,但解决方案是什么?Php有一些函数可以更改编码。它们确实起作用(但不像预期的那样——产生不同的角色)。此外,Live Server是一个香港服务器(CENTOS),它完全支持我与其他脚本的体验。是的,PHP字符串是8位字符串,并且可以将Unicode文本编码为具有任何可能编码的字节,并将这些字节放入PHP字符串中。通常,只要您始终知道正在使用什么编码,这种方法就可以工作。然而,文件系统函数就是其中之一,PHP假定字符串中的字节使用某种编码。
for f in `find . -type f`; do
g=`echo "$f" | sed -e 's/#U/\\\\u/g'`
h=`/usr/bin/printf "$g"`
if test "$h" != "$f"; then
echo mv "$f" "$h"
fi
done
for f in `find . -type f`; do
g=`echo "$f" | sed -e 's/#U/\\\\u/g'`
h=`/usr/bin/printf "$g"`
if test "$h" != "$f"; then
mv "$f" "$h"
fi
done