I use X-SendFile Apache Module to download large files from the server. Downloads work well. However, when the download starts, I need to output some text to the browser, such as: "Thanks for downloading the file...."
My problem is, that I can not do both in one script. I can either download the file, and then no text is output to the screen. Or, I can output the text to the screen, but then the download script won't start.
How to do both tasks in one PHP script please - downloading a file and sending text content to the browser/webpage? The problem probably originates in HTTP output headers, but I do not know how to solve it.
This it the sample code I use to download files via X-SendFile
(works properly on its own):
header('Content-Description: File Transfer');
header("Content-Disposition: attachment; filename=\"". basename($filePath) . "\"");
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
header('Content-Length: ' . filesize($filePath));
header("X-Sendfile: $filePath");
For completion, this is my test echo""
string. If it is placed above the X-Sendfile
code, it gets output, but download will not start. If it is put below the X-Sendfile
code, the file gets downloaded, but nothign is echoed to the browser:
echo "SUCCESS!!!";
ob_flush();
Constraint:
I need to be able to download the file easily via URL. Example, www.mydomain.com/?fileID=asl523n53twteHLfga
. In other words, the PHP download script is within index.php
. When the user enters www.mydomain.com
, the domain landing page gets displayed. However, when the additional $_GET
variable is passed, PHP script recognizes that, and should display Thank you for downloading... instead of the landing page.
A workaround is welcome. Important is to achived the desired result while keeping the above constraint. Tahnk you very much.
How about adding a separate download page that will download the file (i.e. download.php?fileID=XYZ
) and having your index page show a message like so:
<?php
function homeScreen() {
// your home content
}
function downloadFileScreen ($id) {
?>
<h2>Thank you for your download!</h2>
Your download should start automatically, if it does not, click
<a href="download.php?fileID=<?php print $id; ?>">here</a>
<script type="text/javascript">
window.setTimeout('location.href="download.php?fileID=<?php print $id; ?>"',3000);
</script>
<?php
}
if (isset($_GET['fileID'])) {
$id= $_GET['fileID'];
downloadFileScreen ($id);
?>
} else {
// no ID passed, show home screen
homeScreen();
}
?>
I haven't heard of any browser support mixing both download and HTTP content display in a single request, but I'll have a look if this can be achieved using ob_start()
and ob_flush()
.