PHP解压ZIP乱码问题

php版本:PHP 5.6.28

原来的解压代码:

    $zip = new ZipArchive();
    $flag = $zip->open($filePath);
    if ($flag !== true) {
        return $retJson;
    }
    $zip->extractTo($extractPath);
    $zip->close();

如果zip文件含有文件名是B1+1231+伊利.jpg类似的文件,解压出来是B1+1231+?i?ة???.jpg 这样的乱码

解决方法1,适用于php7.x版本。

重点在$statInfo = $zip->statIndex($i,\ZipArchive::FL_ENC_RAW);这行代码上。

<?php

function extractZipToFile($zipName,$dir){
    $zip = new \ZipArchive;
    if ($zip->open($zipName) === TRUE) {
        if(!is_dir($dir)) mkdir($dir,0775,true);
        $docnum = $zip->numFiles;
        for($i = 0; $i < $docnum; $i++) {
            $statInfo = $zip->statIndex($i,\ZipArchive::FL_ENC_RAW);
            //$statInfo = $zip->statIndex($i);
            $filename = transcoding2($statInfo['name']);
            echo $filename . "\n";
            if($statInfo['crc'] == 0) {
                //新建目录
                if(!is_dir($dir.'/'.substr($filename, 0,-1))) mkdir($dir.'/'.substr($filename, 0,-1),0775,true);
            } else {
                //拷贝文件
                copy('zip://'.$zipName.'#'.$zip->getNameIndex($i), $dir.'/'.$filename);
            }
        }
        $zip->close();
        return true;
    }else{
        return false;
    }
}

function transcoding2($fileName){
   return iconv('UTF-8', 'GBK', $fileName);
}

function transcoding($fileName){
    $encoding = mb_detect_encoding($fileName,['UTF-8','GBK','BIG5','CP936']);
    if (DIRECTORY_SEPARATOR == '/'){    //linux
        $filename = iconv($encoding,'UTF-8',$fileName);
    }else{  //win
        $filename = iconv($encoding,'GBK',$fileName);
    }
    return $filename;
}

extractZipToFile("fuzhou_zw.zip", "/home/vv/facemng/dest")
?>

解决方法2:使用pclzip.lib.php,但是要做点改造。适用php5.6+版本

function unzipFile($zipFile, $extractPath) {
    global $cLog;
    $archive = new PclZip($zipFile);
    $list = $archive->extract(PCLZIP_OPT_PATH, $extractPath);
    $cLog->TRACE("extract list=" . json_encode($list));
    return;    
}

改造的代码,增加了编码转换

public function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
{
        // ----- Add the path
        if ($p_path != '') {
            $encode = mb_detect_encoding($p_entry['filename'], array("ASCII", 'UTF-8', "GB2312", "GBK", 'BIG5'));
            if ($encode != "UTF-8") {
                $p_entry['filename'] = mb_convert_encoding($p_entry['filename'], 'UTF-8', 'gb2312');
            }
            $p_entry['filename'] = $p_path."/".$p_entry['filename'];
        }
}

解决方法3:调用python代码

单独在php中可以试验成功,但是放在项目中失败。报错:

“UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 41-42: ordinal not in range(128)”

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# unzip.py

import os
import sys
import zipfile
import codecs


def unzip_file(zip_file_name, target_path):
    # print "Processing File " + sys.argv[1]
    # print "target path " + sys.argv[2]

    if not os.path.exists(target_path) and target_path != "":
        os.makedirs(target_path)
    file = zipfile.ZipFile(zip_file_name, "r")
    for name in file.namelist():
        utf8name = name.decode('gbk')
        # print "Extracting " + utf8name
        data = file.read(name)
        fo = codecs.open(target_path + utf8name, "w+b")
        fo.write(data)
        fo.close()
    file.close()
    return 0


if __name__ == '__main__':
    unzip_file(sys.argv[1], sys.argv[2] + "/")

解决方法4:调用unzip命令解压

在单独的php文件中可以成功,放在项目中失败

unzip -O CP936 xxx.zip (用GBK, GB18030也可以)  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值