文件名中带有重音字符的 PHP ZipArchive

Posted

技术标签:

【中文标题】文件名中带有重音字符的 PHP ZipArchive【英文标题】:PHP ZipArchive with accent chars in filenames 【发布时间】:2015-07-01 08:47:00 【问题描述】:

我正在 UNIX 系统上使用 php 5.3.10 和 Zip 版本 1.12.5 和 Libzip 版本 0.11.2 创建 ZIP 存档:

<?php
$zip = new ZipArchive();
$test_zip = "./test.zip";
if ($zip->open($test_zip, ZIPARCHIVE::CREATE)===TRUE)

    $zip->addFromString("Liste client à exporter.txt","Content line 1\nContent line 2\n");
    $zip->close();

    if(file_exists($test_zip))
    
        header ("Content-Type: application/octet-stream");
        header ("Accept-Ranges: bytes");
        header ("Content-Length: ".filesize($test_zip));
        header ("Content-Disposition: attachment; filename=\"test.zip\"");
        header ("Cache-Control: max-age=60");
        readfile($test_zip);
        unlink ($test_zip);
    

?>

当我使用内部 ZIP 在 Windows 7 上打开生成的 ZIP 文件 test.zip 时,我看到存档中的文件类似于“Liste client +а exporter.txt”而不是“Liste client à exporter.txt ”。 但是如果用 7z 打开它,文件名是正确的,带有重音。 PHP 文件采用 UTF-8 编码。

已解决 问题出在 Windows 7 中(补丁 KB2704299)

File names are corrupted after you decompress a .zip file in Windows 7 or in Windows Server 2008 R2

【问题讨论】:

以解密格式打开的压缩文件? 不明白你的意思。下载后会自动打开。双击zip文件时效果相同。 究竟是什么问题 问题是当使用内部 Windows arhciver 打开存档时,它显示的文件名没有重音符号。 【参考方案1】:

有同样的问题(我是法国人,所以我知道口音的问题)。

为了避免这个问题,我使用了一个外部 zip 命令。

对于 Linux:

exec("cd \"".$the_directory_you want_to_zip."\" && zip -0 -r \"".$path_zip."\" .");

【讨论】:

它没有帮助。相同的效果:内部窗口向上压缩相同的 +a。使用 7z 名称是正确的。【参考方案2】:

不确定今天 Windows 10 和 Php7 的当前状态,但万一有人仍然对 Windows 上的 zip 重音有问题。

压缩时需要将文件名转换为IBM850,从zip中提取时需要转换回UTF8, ISO-8859-1, CP1252

//zipping
$relativePath = iconv('UTF-8', 'IBM850', $relativePath);
$zip->addFile($filePath, $relativePath);

//extracting
$relativePath = iconv('IBM850', 'UTF-8', $zip->getNameIndex($i));
$zip->renameIndex($i, $relativePath);
$zip->extractTo($destination, $relativePath);

【讨论】:

以上是关于文件名中带有重音字符的 PHP ZipArchive的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 表中带有重音符号的字符串在 R (RODBC) 中返回为 NA

PHP 过滤器用无重音符号替换重音字符

无法使用php读取数组中的重音名称[重复]

PHP 从字符串中删除重音符号

如何将重音字符与 PHP preg 匹配?

PHP serialize() 带有重音字符导致不完整的序列化