Я создаю и загружаю ZIP-файл, используя /usr/bin/zip
в PHP. Проблема в том, что zip-файл содержит файлы csv с именами, отличными от ASCII. Я получил загруженный файл нулевого байта, и файл недействителен.
chdir($tmp_dir); // this is the directory where the files are written into
// CSV files that will be included in the zip file.
// assuming that the file already exist in $tmp_dir
$files = array();
$filename = "ショップ" . date("Ymd") . ".csv";
$fpath = $tmp_dir. DS . mb_convert_encoding($filename, "SJIS", "UTF-8");
$files[] = $fpath;
// The zip file to be created
$zip_file = "archive_" . date("Ymd").".zip";
$cmd = "/usr/bin/zip $zip_path *.csv";
exec($cmd);
// Force download
$fpath = $zip_file;
header("Content-Type: application/zip");
header('Content-Disposition: attachment; filename="' . $zip_path . '"');
header('Accept-Ranges: bytes');
if ($this->isIE()) {
header("Cache-Control:private");
header("Pragma:private");
}
header('Content-Length: ' . filesize($fpath));
readfile($fpath);
Я старался ZipArchive, но такая же проблема возникает.
chdir($tmp_dir); // this is the directory where the files are written into
// CSV files that will be included in the zip file.
// assuming that the file already exist in $tmp_dir
$files = array();
$filename = "ショップ" . date("Ymd") . ".csv";
$fpath = $tmp_dir. DS . mb_convert_encoding($filename, "SJIS", "UTF-8");
$files[] = $fpath;
// The zip file to be created
$zip_file = "archive_" . date("Ymd").".zip";
$zip = new ZipArchive();
$zip->open($zip_path, ZipArchive::CREATE);
foreach ($files as $v) {
$zip->addFile(basename($v));
}
$zip->close();
// Force download
$fpath = $zip_file;
header("Content-Type: application/zip");
header('Content-Disposition: attachment; filename="' . $zip_path . '"');
header('Accept-Ranges: bytes');
if ($this->isIE()) {
header("Cache-Control:private");
header("Pragma:private");
}
header('Content-Length: ' . filesize($fpath));
readfile($fpath);
Есть ли обходной путь для этого? Когда я удалил японские символы из имени файла, это нормально.
Я решил эту проблему с помощью функции Iconv преобразовать имена файлов в правильную кодировку.
$filename = iconv('SJIS', 'CP392//TRANSLIT', "ショップ" . date("Ymd") . ".csv");
$fpath = $tmp_dir. DS . $filename;
Это означает, что он преобразует входную кодировку SJIS к выходной кодировке CP392 для имени файла. CP392 является кодовая страница за Shift JIS.
Кодовая страница 932 (сокращенно CP932, также известная под названием IANA
Windows-31J) является расширением Microsoft Shift JIS для включения NEC
специальные символы (строка 13), выбор расширений IBM для NEC (строки 89
до 92) и расширения IBM (строки от 115 до 119). Наборы кодированных символов
JIS X0201: 1997, JIS X0208: 1997 и эти расширения. Окна-31j
часто принимается за Shift JIS: в то время как подобное
важно для программистов, желающих избежать моджибаке, и
хорошая причина использовать однозначный UTF-8 вместо этого. Название windows-31J
однако, IANA и не признаны Microsoft, которая исторически
вместо этого использовал shift_jis.
Других решений пока нет …