I have a script that allows users to download a zip file on demand. It works 100% in computer browsers, but it does not work in Android / mobile browsers, with the exception of Opera (mobile).
Here is my script.
$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;
Here is my purge() function
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);
On my Android phone, the zip file downloads but contains <h1>Nothing to export</h1> , which displays it as an invalid zip file.
So, my problem is that the block is executed only in mobile browsers (except Opera), and then continues to load the zip code if it should be exited , if $count is not zero at all?
I debugged it using Fiddler and the requests are all the same, but the result is different, why?
Is this a bug in PHP? Because if you look at my code, the purge() function should output errors indicating that the headers have already been sent, but it just keeps loading the zip file.
Browsers:
- Dolphin (+ beta)
- Firefox
- Android default browser
- Boat browser
Checked PHP versions:
- 5.3.13 (Production, shared server)
- 5.1.4
It makes me go crazy.
@Alix This is the weirdest mistake I have ever seen. I do not see any logical errors here. In order for the script to initiate the download, the files actually have to be added to the zip. Now on my phone it says that no files have been added, but there is a zip file in the temp folder. Moreover, if no files have been added ( $count = 0), then the script should exit() therefore, the exit() function) only with the message <h1>Nothing to export</h1> . But it continues to load the zip file (which does not currently exist, but in the temp folder it does). The zip file is corrupted because it contains <h1>Nothing to export</h1>
Alix wrote: * what happens if you comment out the exit call before serving the file?
It talks about the readfile error, then readfile zip file in UNICODE character mascots. I can say this is a zip file because it starts with PK and contains the names of the exported images.
Alix wrote:
If this does not work, you can change exit('<h1>Nothing to export</h1>'); to exit (var_dump ($ _ REQUEST)); this way you can check for possible errors when submitting the form by checking the Zip file.
Interesting. It only prints cookies and the $ _GET parameter. If I put the code in your sentence at the beginning of the script, and in the block that adds the files to zip, it prints all the $_POST variables.
There is clearly a bug in PHP. It should end when calling exit , but that is not the case. And remember that this only happens in mobile browsers other than Opera. I will cry for blood now.