4

我有一个脚本,可让用户根据要求下载 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 文件的内容。

所以我的问题是,该块如何仅在移动浏览器(Opera 除外)上执行,然后在它应该有的情况下继续下载 zip,如果它exited完全$count为零?

我使用 Fiddler 对其进行了调试,请求都相同,但输出不同,为什么?

这是PHP中的错误吗?因为如果您查看我的代码,该函数purge()应该输出错误,说明标头已发送,但它只是继续下载 zip 文件。

浏览器:

  • 海豚(+Beta)
  • 火狐
  • 默认安卓浏览器
  • 船浏览器

测试的 PHP 版本:

  • 5.3.13(生产、共享服务器)
  • 5.1.4

这让我现在发疯了。


@Alix 这是我见过的最奇怪的错误。我在这里没有认真看到任何逻辑错误。对于启动下载的脚本,实际上必须将文件添加到 zip 中。现在在我的手机上,它说没有添加任何文件,但文件temp夹中有一个 zip 文件。此外,如果没有添加文件($count= 0),那么脚本应该终止(因此exit()函数)只带有一条消息<h1>Nothing to export</h1>。但它会继续下载 zip 文件(此时它不存在,但在 temp 文件夹中存在)。zip 文件最终损坏,因为它包含<h1>Nothing to export</h1>

Alix 写道: * > 如果您在提供文件之前注释掉退出调用会发生什么?

它说readfile错误,然后以乱码的 UNICODE 字符清除 zip 文件。我可以说它是 zip 文件,因为它开头PK并包含要导出的图像的名称。

阿利克斯写道:

如果这不起作用,您可能想更改exit('<h1>Nothing to export</h1>');为 exit(var_dump($_REQUEST));,这样您就可以通过检查 Zip 文件来检查表单提交中可能存在的错误。

有趣的。它只打印 cookie 和 $_GET 参数。如果我将代码放在脚本开头的建议中以及将文件添加到 zip 的块中,它会打印所有$_POST变量。

这里显然有一个 PHP 部分的错误。它应该在被调用时终止,exit但它不会。请注意,这只发生在除 Opera 之外的移动浏览器上。我现在要哭血了。

4

1 回答 1

0

您确定其他浏览器设置$_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('Content-Length: ' . intval(filesize($zip_name)));
header('Content-Transfer-Encoding: binary');

如果这不起作用,您可能想更改exit('<h1>Nothing to export</h1>');exit(var_dump($_REQUEST));,这样您就可以通过检查 Zip 文件来检查表单提交中可能存在的错误。

于 2012-10-04T21:51:49.693 回答