我有一个脚本可以让用户根据要求下载一个 zip 文件。它在计算机浏览器上 100% 有效,但不适用于 Android/移动浏览器,仅 Opera(移动)除外。
这是我的脚本。
$leads = new Packer($zip_name);
$index = 1;
$count = 0;
foreach($cLeads->lastUnitInfo['leads'] as $lead)
{
// build a request string
$export = 'export_lead_'.$index;
$req = $_POST[$export];
// add it to the zip file
if(isset($req) && $req == '1')
{
// debug only
//echo 'adding lead: '.$lead['file_name'].'<br />';
$leads->addLead('leads/'.$lead['file_name'],$lead['item_name']);
$count++;
//echo 'count: '.$count.'<br/>';
}
$index++;
}
// debug
//exit('count: '.$count); // displays same results on all browsers.
// we got anything packed ?
if($count <= 0) //// <-------- BLOCK OF BUG ON MOBILE PHONE
{
if(file_exists($zip_name))
unlink($zip_name); // delete the zip file created.
exit('<h1>Nothing to export</h1>');
} ///// <---------------------- END BLOCK
// download the leads here.
$leads->purge();
exit;
这是我的 purge()
功能
public function purge($zip_name = 'leads.zip')
{
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.$zip_name.'"');
ob_clean();
flush();
readfile($this->zip_name);
// errors will be disabled here
unlink($this->zip_name);
}
在我的 Android 手机上,zip 文件已下载但包含 <h1>Nothing to export</h1>
将其呈现为无效的 zip 文件。
所以我的问题是,该 block 如何只在移动浏览器(Opera 除外)上执行,然后在它应该有 exited
时继续下载 zip?如果$count
是零吗?
我用Fiddler调试了一下,请求都是一样的,输出却不一样,为什么?
这是 PHP 中的错误吗?因为如果你看我的代码函数 purge()
应该输出错误消息,说明 header 已发送,但它只是继续下载 zip 文件。
浏览器:
- 海豚(+测试版)
- 火狐
- 默认安卓浏览器
- 船浏览器
测试的 PHP 版本:
- 5.3.13(生产,共享服务器)
- 5.1.4
这让我抓狂。
@Alix 这是我见过的最奇怪的错误。我在这里没有认真地看到任何逻辑错误。对于启动下载的脚本,实际上必须将文件添加到 zip。现在在我的手机上,它说没有添加任何文件,但是 temp
中有一个 zip 文件。文件夹。此外,如果没有添加文件($count
= 0),那么脚本应该终止(因此是exit()
函数)并只显示一条消息<h1>Nothing to export</h1>
。 .但它继续下载 zip 文件(此时不存在,但在临时文件夹中存在)。 zip 文件最终被损坏,因为它包含 <h1>Nothing to export</h1>
阿利克斯写道: *> 如果您在提供文件之前注释掉退出调用会怎样?
它说 readfile
然后错误以乱码的 UNICODE 字符清除 zip 文件。我可以看出它是 zip 文件,因为它以 PK
开头并包含正在导出的图像的名称。
Alix 写道:
If this doesn't work, you may wanna change
exit('<h1>Nothing to export</h1>');
to exit(var_dump($_REQUEST));, that way you may check for possible bugs in the form submission by inspecting the Zip file.
很有趣。它只打印 cookie 和 $_GET 参数。如果我将代码放在脚本开头的建议中以及将文件添加到 zip 的 block 中,它会打印所有 $_POST
变量。
这里显然存在 PHP 部分的错误。它应该在 exit
时终止被称为但它没有。请注意,这只发生在 Opera 以外的移动浏览器上。我现在要哭了。
最佳答案
您确定其他浏览器正在设置 $_POST[$export]
到正确的值?
另外,你应该先ob_[end_]clean()
然后输出标题,而不是相反:
public function purge($zip_name = 'leads.zip')
{
ob_end_clean();
flush();
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.$zip_name.'"');
readfile($this->zip_name);
// errors will be disabled here
unlink($this->zip_name);
}
此外,您可能需要设置这些 header :
header('Content-Length: ' . intval(filesize($zip_name)));
header('Content-Transfer-Encoding: binary');
如果这不起作用,您可能需要更改 exit('<h1>Nothing to export</h1>');
至 exit(var_dump($_REQUEST));
,这样您就可以通过检查 Zip 文件来检查表单提交中可能存在的错误。
关于PHP zip 下载错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12735532/