【发布时间】:2019-06-10 16:24:18
【问题描述】:
我遇到的问题是,如果在 Web 服务器上启用了 Zlib 压缩,则在系统的 download_helper.php 文件中使用 CodeIgniter 的 force_download 函数下载任何 zip 文件会破坏存档文件并阻止用户打开它。
这是压缩文件后的force_download 函数,其中压缩了XLSX 文件:
function force_download($filename = '', $data = '')
{
if ($filename == '' OR $data == '')
{
return FALSE;
}
// Try to determine if the filename includes a file extension.
// We need it in order to set the MIME type
if (FALSE === strpos($filename, '.'))
{
return FALSE;
}
// Grab the file extension
$x = explode('.', $filename);
$extension = end($x);
// Load the mime types
if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
}
elseif (is_file(APPPATH.'config/mimes.php'))
{
include(APPPATH.'config/mimes.php');
}
// Set a default mime if we can't find it
if ( ! isset($mimes[$extension]))
{
$mime = 'application/octet-stream';
}
else
{
$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
}
// Generate the server headers
if (strpos($_SERVER['HTTP_USER_AGENT'], "MSIE") !== FALSE)
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
header("Content-Length: ".strlen($data));
}
else
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".strlen($data));
}
exit($data);
}
启用 Zlib 还会在 Excel 文件中产生乱码,从而破坏 PHPExcel,如图所示。
单个XLSX文件的PHPExcel下载功能。这是整个 Excel 生成器、zip 和下载器函数的要点https://gist.github.com/TheWebAuthor/5773e56086df4317c7cf54aab45df328
ob_end_clean();
header('Content-Description: File Transfer');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment; filename=' .$fileinfo['filename'] . '_' . $customerId . '_' . date("mdy") . '.xls');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
是否有适当的解决方法来启用 Zlib 而不会破坏这些功能?
【问题讨论】:
-
如果我没记错的话,force_download 函数会为您发送标头。
-
另外,您可能不应该使用
pragma:public,因为它表示任何缓存都应该可以随意缓存文档。您可能正在查看缓存(和损坏)的文档,而不是文件的最新版本。 -
@S.Imp 将
pragma:public更改为pragma:no-cache,打开存档时仍然报错。 -
请看下面的答案,如果我误解了,请澄清。
-
那是什么版本的 Codeigniter? latest force_download 接受第三个参数。如果您的 Codeigniter 版本较旧,则它也可能缺少您正在下载的任何文件的正确 mime 类型。不幸的是,您发布的代码根本没有告诉我们您实际发送给用户的文件类型。
标签: php apache codeigniter phpexcel zlib