4

ユーザーが要求に応じて zip ファイルをダウンロードできるようにするスクリプトがあります。コンピューターのブラウザーでは 100% 動作しますが、Opera (モバイル) のみを除いて、Android/モバイル ブラウザーでは動作しません。

これが私のスクリプトです。

    $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場合に必要なときに zip をダウンロードし続けるのはどうしてですか?$count

Fiddler を使用してデバッグしましたが、要求はすべて同じですが、出力が異なります。なぜですか?

これはPHPのバグですか?私のコードを見ると、関数purge()はヘッダーが既に送信されているというエラーを出力するはずですが、zip ファイルのダウンロードを続行するためです。

ブラウザ:

  • ドルフィン (+ベータ版)
  • ファイアフォックス
  • デフォルトの Android ブラウザ
  • ボートブラウザ

テスト済みの 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 は次のように書いています: * > ファイルを提供する前に exit 呼び出しをコメントアウトするとどうなりますか?

エラーがreadfile表示され、意味不明な UNICODE 文字で zip ファイルが削除されます。で始まり、PKエクスポートされる画像の名前が含まれているため、zipファイルであることがわかります。

アリックスは次のように書いています。

これが機能しない場合は、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');

これがうまくいかない場合は、Zip ファイルを調べて、フォームの送信にバグがないかどうかを確認するために、 に変更exit('<h1>Nothing to export</h1>');することをお勧めします。exit(var_dump($_REQUEST));

于 2012-10-04T21:51:49.693 に答える