Php Shell-使用重音符号解压文件夹

Php Shell-使用重音符号解压文件夹,php,shell,zip,unzip,Php,Shell,Zip,Unzip,我在Windows中使用以下结构创建了一个“.zip”: myfile.zip - trénsfèst - file1.png - file2.png - file3.png 使用PHP,我发送一个shell\u exec将myfile.zip放在我的服务器上。在我的shell文件中,我需要解压这个文件以获得特定文件夹中的结构。当我执行解压myfile.zip时,所有的重音都不会被解释: Archive: myfile.zip crea

我在Windows中使用以下结构创建了一个“.zip”:

myfile.zip
    - trénsfèst
        - file1.png
        - file2.png
        - file3.png
使用PHP,我发送一个
shell\u exec
myfile.zip
放在我的服务器上。在我的shell文件中,我需要解压这个文件以获得特定文件夹中的结构。当我执行
解压myfile.zip
时,所有的重音都不会被解释:

Archive:  myfile.zip
creating: tr?n'sf?rt/
inflating: tr?n'sf?rt/file1.png
inflating: tr?n'sf?rt/file2.png
inflating: tr?n'sf?rt/file3.png
当我试图删除文件夹时,有一些方块代替了重音符号。有没有一个解决方案来解压我的文件夹与所有的口音


谢谢

Windows通常根据区域设置对文件名进行编码。例如,对于俄语设置,它通常在CP866中编码文件名。文件名放在同一区域设置的Zip中,即区域设置取决于创建存档的系统

检测编码

我在几年前就知道了,我得出的结论是,一般来说,没有办法可靠地检测编码。在PHP中,您可以尝试使用
ZipArchive
和:

其中,
ru
是语言代码(所有语言代码都可以通过
enca-列出语言
)获得)。但这需要你猜语言。要将文件名从一种编码转换为UTF-8,您可以使用
enconv
,例如:

ls -1 folder | enconv -L russian -x UTF-8
但是,同样,你需要猜测语言

因此,我建议尝试使用上述方法之一检测编码,并要求用户从所有可用编码的列表中选择编码。默认情况下,可能会在列表中选择自动检测到的编码。就我个人而言,我选择让用户在没有智能自动检测的情况下选择编码

当您知道源编码时

解压支持使用
-p
选项的管道流。但它只适用于批量数据。也就是说,它不会将流分离为文件,将所有未压缩的内容传递给程序:

解压-p foo | more=>通过管道将foo.zip的内容发送到程序more中

解析原始流显然是一项困难的任务。一种方法是将文件提取到目录中,然后使用如下脚本转换文件名:

$path = $argv[1];
$from_encoding = isset($argv[2]) ? $argv[2] : 'CP866';

if ($handle = opendir($path)) {
  while ($file = readdir($handle)) {
    rename($file, iconv($from_encoding, 'UTF-8', $file));
  }
  closedir($handle);
}
示例用法:

php script.php directory Windows-1252
php script.php file.zip Windows-1252
或者,使用
ZipArchive
,如下所示

$zip = new ZipArchive;

$filename = $argv[1];
$from_encoding = isset($argv[2]) ? $argv[2] : 'CP866';

$zip->open($filename) or die "failed to open $filename\n";

for ($i = 0; $i < $zip->numFiles; ++$i) {
  $zip->renameIndex($i, iconv($from_encoding,'UTF-8', $zip->getNameIndex($i)));
}
$zip->extractTo('/target/directory/');

$zip->close();

谢谢Ruslan Osmanov但我找到了解决办法。 解压我的zip文件后,我使用
convmv
,因此我的过程如下:

unzip myfile.zip
convmv --notest -r -f WINDOWS-1252 -t utf8

感谢这篇文章:

你能以某种方式分享这个文件吗?我想我知道如何修复它,但我想在发布答案之前检查解决方案。只需在windows上创建一个带重音的文件夹(带或不带文件),然后用winrar或7zip压缩即可。该文件不是特定的。问题是Zip中的文件名编码取决于系统区域设置。在不同的Windows设置上,结果可能不同。如果您想快速解决问题,请共享该文件。您将在我的windows上解决问题,但我的应用程序的所有用户都可以使用.zip,因此我无法向您发送该文件。是的,我认为问题来自LCALE。我的答案包含convmv btw。此外,您不能断言它将始终是Windows-1252,因为它取决于源语言环境。最后,由于您的问题标记为php,因此我使用ziparchive和iconv的解决方案更合适。
php script.php file.zip Windows-1252
unzip myfile.zip
convmv --notest -r -f WINDOWS-1252 -t utf8