我有以下代码:
$files = ftp_nlist($conn_id, "/path/to/files");
$zip = new ZipArchive;
$res = $zip->open('filename.zip', ZipArchive::CREATE);
if ($res === TRUE) {
foreach ($files as $item) {
if ($item != '.' && $item != '..') {
// Get file contents
ob_start();
@ftp_get($conn_id, "php://output", "/path/to/files/{$item}", FTP_BINARY);
$data = ob_get_contents();
ob_end_clean();
$zip->addFromString($item, $data);
}
}
// ...
}
不幸的是,zip文件中的文件名已损坏。例如,ßäÄçö.txt变为+ƒ+ñ+ä+º+ | .txt。
我假设这可以通过使用iconv
来解决,但我找不到任何产生所需结果的编码对。据我所知,文件名存储为UTF-8。当我没有压缩文件但只是使用
// ...
header("Content-Disposition: attachment; filename*=UTF-8''".rawurlencode($item));
//...
echo $data;
没有字符损坏。
答案 0 :(得分:1)
C3 9F C3 A4 C3 84 C3 A7 C3 B6
。如果您将这些字节读作CP-437,则会得到“├ƒ├ñ├ä├º├╢”。如果您将所有“├”(C3
)更改为“+”(2B
)并将最后一个字符更改为“|”,则会得到“+ƒ+ñ+ä+º+ | ”
我不知道为什么“├”变成“+”,也不知道为什么“╢”变成“|”。我尝试在Vim中保存一个名为“├ƒ├ñ├ä├º├╢.txt”的文本文件,然后创建了一个名为“+ƒ+ñ+ä+º+ | .txt”的文件。但是当我在记事本中尝试相同的操作时,它创建了正确的文件名“├ƒ├ñ├ä├º├╢.txt”。因此,无论Zip文件中的字节发生了什么,都与Vim的作用相同。
附录D中的Zip File Format Specification表示文件名必须是CP-437或UTF-8,所以看起来你的文件名被视为CP-437,加上任何额外的步骤都是字节C3
和B6
。也许PHP的ZipArchive有一个解决方法,或者你可以使用不同的Zip库。快速搜索“php ziparchive utf-8”发现了很多结果,但我没有立即看到解决方案。