首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 解決 ZIP 解壓縮檔名亂碼:GBK 轉 UTF-8 實戰代碼

     編輯:PHP 綜合知識

問題根源

Windows 建立的 ZIP 檔,檔名編碼通常為 GBK/CP936;Linux PHP 環境預設 UTF-8,直接解壓會產生亂碼檔名。

解決代碼

<?php
$zip = zip_open('other.zip');
if (!$zip) die("無法開啟 ZIP");

while ($entry = zip_read($zip)) {
    $size = zip_entry_filesize($entry);
    // 關鍵:將檔名從 GBK 轉為 UTF-8
    $name = iconv('GBK', 'UTF-8', zip_entry_name($entry));

    if (!$size) { // 目錄
        if (!is_dir($name)) mkdir($name, 0755, true);
        continue;
    }

    if (!zip_entry_open($zip, $entry)) continue;
    $content = zip_entry_read($entry, $size);
    file_put_contents($name, $content);
    echo "$size\t$name\n";
    zip_entry_close($entry);
}
zip_close($zip);
?>

進階健壯版

function extractZip($zipPath, $dest = '.', $fromEncoding = 'GBK', $toEncoding = 'UTF-8') {
    $zip = new ZipArchive();
    if ($zip->open($zipPath) !== true) throw new Exception("無法開啟 $zipPath");

    for ($i = 0; $i < $zip->numFiles; $i++) {
        $stat = $zip->statIndex($i);
        $rawName = $stat['name'];
        $name = iconv($fromEncoding, $toEncoding . '//IGNORE', $rawName);
        $target = $dest . DIRECTORY_SEPARATOR . $name;

        if (substr($rawName, -1) === '/') { // 目錄
            if (!is_dir($target)) mkdir($target, 0755, true);
            continue;
        }

        // 確保父目錄存在
        $dir = dirname($target);
        if (!is_dir($dir)) mkdir($dir, 0755, true);

        $content = $zip->getFromIndex($i);
        file_put_contents($target, $content);
    }
    $zip->close();
}

// 使用
extractZip('other.zip', './extracted');

常見編碼對照

來源環境常見編碼iconv 參數
Windows 中文版GBK / CP936`iconv('GBK', 'UTF-8', ...)`
Linux/macOSUTF-8無需轉換
舊版日文 WindowsShift_JIS`iconv('SJIS', 'UTF-8', ...)`
舊版繁中 WindowsBig5`iconv('Big5', 'UTF-8', ...)`

注意事項

  • PHP `ZipArchive` 類別需安裝 `php-zip` 擴展(`apt-get install php-zip` / `yum install php-pecl-zip`)。
  • 檔名含有不可轉換字元時,`//IGNORE` 會略過,或改用 `//TRANSLIT` 嘗試近似轉換。
  • 大檔案解壓建議分塊讀寫,避免記憶體耗盡。

若 ZIP 來源未知,可嘗試 `mb_detect_encoding($rawName, ['GBK','UTF-8','BIG5','SJIS'])` 自動偵測編碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved