[PHP] mb_convert_encoding修复压缩文件乱码

使用 ZipArchive 的 statIndex 获取压缩文件的文件名时出现乱码无法仅使用 mb_convert_encoding 处理的问题。


下面是不能很好编码的代码和执行结果。
下面的代码将在与 index.php 相同的目录中加载“test.zip”。
“Test.zip”中有“Test.pdf”。

<?php
    $zip = new ZipArchive;
    if ($zip->open("./テスト.zip") === true) {
        $idx = 0;
        $zipEntry = $zip->statIndex($idx);
        $entryName = $zipEntry['name'];

        echo "エンコード無しのファイル名:" . $entryName . "<br>";

        $encode = mb_detect_encoding($entryName, "Shift-JIS,EUC-JP");
        echo "文字コードチェックした結果:" . $encode . "<br>";

        $to = "UTF-8";
        $from = "SJIS";
        $destName = mb_convert_encoding($entryName, $to, $from);
        echo "$from から$to にエンコードした結果:" . $destName . "<br>";

        $to = "UTF-8";
        $from = "SJIS-win";
        $destName = mb_convert_encoding($entryName, $to, $from);
        echo "$from から$to にエンコードした結果:" . $destName . "<br>";

        $to = "UTF-8";
        $from = "CP932";
        $destName = mb_convert_encoding($entryName, $to, $from);
        echo "$from から$to にエンコードした結果:" . $destName . "<br>";

        $to = "SJIS";
        $from = "UTF-8";
        $destName = mb_convert_encoding($entryName, $to, $from);
        echo "$from から$to にエンコードした結果:" . $destName . "<br>";

        $to = "SJIS-win";
        $from = "UTF-8";
        $destName = mb_convert_encoding($entryName, $to, $from);
        echo "$from から$to にエンコードした結果:" . $destName . "<br>";

        $to = "CP932";
        $from = "UTF-8";
        $destName = mb_convert_encoding($entryName, $to, $from);
        echo "$from から$to にエンコードした結果:" . $destName . "<br>";

        $zip->close();
    }
?>
エンコード無しのファイル名:âeâXâg.pdf
文字コードチェックした結果:SJIS
SJIS からUTF-8 にエンコードした結果:テ「eテ「Xテ「g.pdf
SJIS-win からUTF-8 にエンコードした結果:テ「eテ「Xテ「g.pdf
CP932 からUTF-8 にエンコードした結果:テ「eテ「Xテ「g.pdf
UTF-8 からSJIS にエンコードした結果:?e?X?g.pdf
UTF-8 からSJIS-win にエンコードした結果:?e?X?g.pdf
UTF-8 からCP932 にエンコードした結果:?e?X?g.pdf

如上所述,无论您编码什么模式,它都不会是原始文件名。 这似乎是由于ZipArchive在statIndexing时自动确定字符代码并应用错误的转换,无法获得Windows环境下使用的字符代码CP932的原始值。 因此,将 ZipArchive::FL_ENC_RAW 添加到 statIndex 的第二个参数。通过这样做,可以防止PHP端的任意字符代码转换,后续转换(mb_convert_encoding)将起作用。 下面是可以很好编码的代码和执行结果。 下面的代码将在与 index.php 相同的目录中加载“test.zip”。 “Test.zip”中有“Test.pdf”。

<?php
    $zip = new ZipArchive;
    if ($zip->open("./テスト.zip") === true) {
        $idx = 0;
        $zipEntry = $zip->statIndex($idx, ZipArchive::FL_ENC_RAW);
        $entryName = $zipEntry['name'];

        echo "エンコード無しのファイル名:" . $entryName . "<br>";

        $encode = mb_detect_encoding($entryName, "Shift-JIS,EUC-JP");
        echo "文字コードチェックした結果:" . $encode . "<br>";

        $to = "UTF-8";
        $from = "SJIS";
        $destName = mb_convert_encoding($entryName, $to, $from);
        echo "$from から$to にエンコードした結果:" . $destName . "<br>";

        $to = "UTF-8";
        $from = "SJIS-win";
        $destName = mb_convert_encoding($entryName, $to, $from);
        echo "$from から$to にエンコードした結果:" . $destName . "<br>";

        $to = "UTF-8";
        $from = "CP932";
        $destName = mb_convert_encoding($entryName, $to, $from);
        echo "$from から$to にエンコードした結果:" . $destName . "<br>";

        $to = "SJIS";
        $from = "UTF-8";
        $destName = mb_convert_encoding($entryName, $to, $from);
        echo "$from から$to にエンコードした結果:" . $destName . "<br>";

        $to = "SJIS-win";
        $from = "UTF-8";
        $destName = mb_convert_encoding($entryName, $to, $from);
        echo "$from から$to にエンコードした結果:" . $destName . "<br>";

        $to = "CP932";
        $from = "UTF-8";
        $destName = mb_convert_encoding($entryName, $to, $from);
        echo "$from から$to にエンコードした結果:" . $destName . "<br>";

        $zip->close();
    }
?>
エンコード無しのファイル名:�e�X�g.pdf
文字コードチェックした結果:SJIS
SJIS からUTF-8 にエンコードした結果:テスト.pdf
SJIS-win からUTF-8 にエンコードした結果:テスト.pdf
CP932 からUTF-8 にエンコードした結果:テスト.pdf
UTF-8 からSJIS にエンコードした結果:?e?X?g.pdf
UTF-8 からSJIS-win にエンコードした結果:?e?X?g.pdf
UTF-8 からCP932 にエンコードした結果:?e?X?g.pdf

如上所述,我能够很好地对其进行编码。

就这样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值