PHP ZipArchive Corrupt в Windows - PullRequest
       6

PHP ZipArchive Corrupt в Windows

19 голосов
/ 07 января 2011

Я использую PHP-класс ZipArchive для создания zip-файла, содержащего фотографии, а затем подаю его в браузер для загрузки.Вот мой код:

/**
 * Grabs the order, packages the files, and serves them up for download.
 *
 * @param string $intEntryID 
 * @return void
 * @author Jesse Bunch
 */
public static function download_order_by_entry_id($intUniqueID) {

    $objCustomer = PhotoCustomer::get_customer_by_unique_id($intUniqueID);

    if ($objCustomer):

        if (!class_exists('ZipArchive')):
            trigger_error('ZipArchive Class does not exist', E_USER_ERROR);
        endif;

        $objZip = new ZipArchive();
        $strZipFilename = sprintf('%s/application/tmp/%s-%s.zip', $_SERVER['DOCUMENT_ROOT'], $objCustomer->getEntryID(), time());

        if ($objZip->open($strZipFilename, ZIPARCHIVE::CREATE) !== TRUE):

            trigger_error('Unable to create zip archive', E_USER_ERROR);

        endif;          

        foreach($objCustomer->arrPhotosRequested as $objPhoto):

            $filename = PhotoCart::replace_ee_file_dir_in_string($objPhoto->strHighRes);
            $objZip->addFile($filename,sprintf('/press_photos/%s-%s', $objPhoto->getEntryID(), basename($filename)));

        endforeach;

        $objZip->close();

        header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($strZipFilename)).' GMT',  TRUE, 200);
        header('Cache-Control: no-cache', TRUE);
        header('Pragma: Public', TRUE);
        header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT', TRUE);
        header('Content-Length: '.filesize($strZipFilename), TRUE);
        header('Content-disposition: attachment; filename=press_photos.zip', TRUE);

        header('Content-Type: application/octet-stream', TRUE);

        ob_start();
        readfile($strZipFilename);
        ob_end_flush();
        exit;

    else:

        trigger_error('Invalid Customer', E_USER_ERROR);

    endif;

}

Этот код очень хорошо работает во всех браузерах, кроме IE.В IE файл загружается правильно, но zip-архив пуст.При попытке извлечь файлы Windows сообщает, что zip-архив поврежден.У кого-нибудь была эта проблема раньше?

Редактировать Обновление: после предложения от @profitphp я изменил свои заголовки на это:

header("Cache-Control: public");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
//header("Content-Description: File Transfer");
//header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=\"pressphotos.zip\"");
//header("Content-Transfer-Encoding: binary");
header("Content-length: " . filesize($strZipFilename));

Также вот скриншотошибки в Windows после открытия в Firefox:

alt text

Эта ошибка возникает как в IE, так и в Firefox в Windows.Он отлично работает в Mac.Кроме того, в Windows размер файла выглядит правильно:

alt text

Редактировать # 2 Эта проблема устранена.Смотрите мой ответ ниже.

Ответы [ 13 ]

0 голосов
/ 25 января 2015

На всякий случай, если кто-то еще несколько часов бьет его / ее по кирпичной стене и страдает, как я.У меня была та же проблема, и ни одно из решений не помогло, пока я не понял, что я загружаю некоторые библиотеки в свой PHP, и одна из них имеет пустую строку после кода?>.При вызове библиотеки с include(/path/to/lib/lib.php); в браузер выводилась пустая строка, в результате чего zip классифицировался как поврежденный Windows.(У Winzip, Total Commander и т. Д. С этим проблем не было).Поэтому убедитесь, что нет импортированной библиотеки или, если она есть, в ней нет пробелов или пустых строк ....

0 голосов
/ 20 февраля 2014

Я использовал метку времени в имени файла zip.Фактически файловая система Windows не поддерживает специальные символы, такие как ": \ / *? <> |"

После удаления ":" из части времени, в которой она работаеткак шарм

0 голосов
/ 25 февраля 2013

Измените свой код:

 header('Content-Length: '.filesize($strZipFilename), TRUE);

С:

header('Content-Length: '.file_get_contents($strZipFilename));
...