Windows 中的 PHP ZipArchive 损坏 [英] PHP ZipArchive Corrupt in Windows

查看:25
本文介绍了Windows 中的 PHP ZipArchive 损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 PHP 的 ZipArchive 类创建一个包含照片的 zip 文件,然后将其提供给浏览器以供下载.这是我的代码:

I am using PHP's ZipArchive class to create a zip file containing photos and then serve it up to the browser for download. Here is my code:

/**
 * 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 存档已损坏.以前有人遇到过这个问题吗?

This code works really well with all browsers but IE. In IE, the file downloads correctly, but the zip archive is empty. When trying to extract the files, Windows tells me that the zip archive is corrupt. Has anyone had this issue before?

编辑 更新:根据@profitphp 的建议,我将标题更改为:

Edit Update: After suggestion from @profitphp, I changed my headers to this:

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));

此外,这是使用 Firefox 打开后 Windows 中的错误屏幕截图:

Also, here is a screenshot of the error in Windows after opening with Firefox:

此错误在 Windows 上的 IE 和 Firefox 中都会发生.它在 Mac 上运行良好.此外,在 Windows 中,文件大小似乎是正确的:

This error occurs in both IE and Firefox on Windows. It works fine in Mac. Also, in Windows, the filesize appears to be correct:

编辑 #2 此问题已解决.请看下面我的回答.

Edit #2 This issue is sovled. See my answer below.

推荐答案

好吧,经过一番折腾,我找到了问题所在.问题来自以下代码行:

Ok, after much strife, I figured out the problem. The issue comes from the following line of code:

$objZip->addFile($filename,sprintf('/press_photos/%s-%s', $objPhoto->getEntryID(), basename($filename)));

出于某种原因,zip 存档中本地(内部)文件名路径的 /press_photos/ 部分导致 Windows 认为 zip 文件已损坏.将该行修改为如下所示后,Windows 正确打开了 zip 文件.呼.

For some reason, the /press_photos/ part of that path for the local (internal) file name inside the zip archive was causing Windows to think the zip file was corrupt. After modifying the line to look like what is below, Windows opened the zip files correctly. Phew.

$objZip->addFile($filename,sprintf('%s-%s', $objPhoto->getEntryID(), basename($filename)));

这篇关于Windows 中的 PHP ZipArchive 损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆