PHP ZipArchive non-English filenames return funky filenames within archive
Asked Answered
R

2

0

This code works properly to make the ZIP file with the wanted files, except the filenames in the archive, which are not in English (in this case they are Hebrew), have weird characters instead of the proper hebrew letters.

<?php
$filesfordown = $_POST['GEMin'];
    if(empty($filesfordown)) 
    {
        echo "No files were seleceted for download.";
    } 
    else 
    {
$zip_name = "RMW." . time() . ".zip";
$zip = new ZipArchive;
$zip->open($zip_name, ZipArchive::CREATE);
foreach ($filesfordown as $filefordown) {
  $zip->addFile($filefordown);
}
$zip->close(); }

header('Content-Type: application/zip');
header("Content-disposition: attachment; filename='$zip_name'");
header('Content-Length: ' . filesize($zip_name));
readfile($zip_name);

ob_flush;
?>

I did some searching around, it seems that iconv, setlocalte, or mb_convert_encoding might help, but whatever I tried didn't work.

Any ideas?

P.S. As a side question, is there a way to not keep directory structure in the zip?

ETA: An example of the $_post may be www.domain.com/path/שלום_01.mp3

Rebbecarebbecca answered 15/12, 2013 at 22:45 Comment(1)
Seems like this may be an old bug: bugs.php.net/bug.php?id=53948Rebbecarebbecca
R
5

Yay! Fixed!

First the code, then an explanation:

<?php 
setlocale(LC_ALL, 'he_IL.UTF-8');
$filesfordown = $_POST['GEMin'];
    if(empty($filesfordown)) 
    {
        echo "לא נבחרו.. נסה שוב";
    } 
    else 
    {
$zip_name = "RMW" . time() . ".zip";
$zip = new ZipArchive;
$zip->open($zip_name, ZipArchive::CREATE);
echo "מכין את ההורדה...";
foreach ($filesfordown as $filefordown) {
  $zip->addFile($filefordown, iconv("UTF-8","CP862",basename($filefordown)));
}
$zip->close(); 

3 things needed to be changed.

  1. Verify that the actual php file is UTF-8.
  2. setlocale() needs to include the .UTF-8 at the end.
  3. ZipArchive does not handle UTF-8 correctly. Must use CP. Hebrew was CP862. Therefore, use extra option $localname for addFile, and its basically iconv("UTF-8","CODE_PAGE_REF",$localname)
Rebbecarebbecca answered 16/12, 2013 at 13:24 Comment(1)
Two notes: 1) Choose the appropriate Code Page, could be Hebrew CP862, Western Europe CP850 or any other. 2) If your filenames differ in Code Page or uses characters from different Code Pages in a single filename, this method won't do it.Ingalls
C
1

It also works with: iconv("UTF-8", "CP852", $nameFile);

Carnauba answered 15/4, 2016 at 22:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.