My php script is converting a PDF file into a zip file containing images for each page of the PDF.
After loading the zip with images I'm transferring the zip to the headers like below.
ob_start();
header('Content-Transfer-Encoding: binary');
header('Content-disposition: attachment; filename="converted.ZIP"');
header('Content-type: application/octet-stream');
ob_end_clean();
readfile($tmp_file);
unlink($tmp_file);
exit();
The download is absolutely working fine in Windows, Linux and Mac.But when I'm requesting the same from an android device (normal browser or Chrome), an unreadable zip is being downloaded. On opening it through the file explorer it says "File is either corrupt or unsupported format" starting from Android 6 (not tested below this version).
I placed the ob_start() and ob_end_clean() function later even then it didn't work.
I checked many answers from stackoverflow but none of them working out like
- Forceful download not working for browser on Android phone on wap site
- Not able to download files with php in android browsers
What is the modification that is needed for android browsers?
<?php include 'headerHandlersCopy.php';
session_start();
ob_start();
//echo session_id()."<br>";
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../css/handleConvertPDFtoJPG.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
<title>Compressing Image</title>
</head>
<body>
<!-- Progress bar -->
<div id="wrapper">
<h1 id="head1">Compressing Image</h1>
<h1 id="head2">Converting Image</h1>
<div id="myProgress">
<div id="myBar">10%</div>
</div>
<br>
</div>
<!-- end -->
<?php
//code to display errors.
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
$session_id = session_id();
$uploadPath = "../upload/pdfUploads/";
$pdfFileNameWithOutExt = basename($_FILES["pdfDoc"]["name"],"pdf");
$dotRemovedFileNameTemp = str_replace(".", "", $pdfFileNameWithOutExt);
$dotRemovedFileName = $session_id.$dotRemovedFileNameTemp;
$imgExt = ".jpg";
$fileNameLocationFormat = $uploadPath.$dotRemovedFileName.$imgExt;
$fileNameLocation = $uploadPath.$dotRemovedFileName;
$status = null;
$imagick = new Imagick();
# to get number of pages in the pdf to run loop below.
# the below function generates unreadable images for each page.
$imagick->pingImage($_FILES['pdfDoc']['tmp_name']);
$noOfPagesInPDF = $imagick->getNumberImages();
$imagick->readImage($_FILES['pdfDoc']['tmp_name']);
$statusMsg = "test";
# writing pdf into images.
try {
$imagick->writeImages($fileNameLocationFormat, true);
$status = 1;
}
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
$status = 0;
}
$files = array();
# storing converted images into array.
# only including the readable images into the
$arrayEndIndex = ($noOfPagesInPDF * 2)-1;
for ($x = $arrayEndIndex; $x >= $noOfPagesInPDF; $x--) {
array_push($files,"{$fileNameLocation}-{$x}.jpg" );
}
# create new zip object
$zip = new ZipArchive();
# create a temp file & open it
$tmp_file = tempnam('.', '');
$zip->open($tmp_file, ZipArchive::CREATE);
# loop through each file
foreach ($files as $file) {
# download file
$download_file = file_get_contents($file);
#add it to the zip
$zip->addFromString(basename($file), $download_file);
}
# close zip
$zip->close();
# file cleaning code
# only those pdf files will be deleted which the current user uploaded.
# we match the sesion id of the user and delte the files which contains the same session id in the file name.
# file naming format is: session_id + destination + fileName + extension
$files = glob("../upload/pdfUploads/{$session_id}*"); // get all file names
foreach($files as $file){ // iterate files
if(is_file($file)) {
unlink($file); // delete file
}
}
// send the file to the browser as a download
ob_end_clean();
header('Content-Description: File Transfer');
header('Content-type: application/octet-stream');
header('Content-disposition: attachment; filename="geek.zip"');
//header("Content-Length: " . filesize($tmp_file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
flush();
readfile($tmp_file);
unlink($tmp_file);
//filesize($tmp_file) causing the "error opening the file" when opening the zip even in PC browsers.
}
?>