Php 使用unicode字符/非UTF重命名文件

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

好吧,我真的和这件事纠缠了一段时间。 我有数千个错误字符的文件,这些文件是服务器从zip文件中错误提取的,产生了服务器以这种方式转换的名称:

原始文件名(示例)为

现在显示在服务器上的文件的形状为

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