I am creating a csv file to download, using a technique similar to using the browser prompt to download a file
$csv_export = .... csv data...;
header("Content-type: text/x-csv");
header("Content-Disposition: attachment; filename=" . $csv_filename . "");
echo($csv_export);
exit;
The file downloads just fine. But this is in WordPress, so when I do a php exit; everything stops and the page appears to hang, and the user needs to do a page reload.
Is there any way to do this and/or force a reload so that it does not appear to user to have hung?
Thanks
First of all, why do you use exit in the first place to stop the processing? You could output your content like this too:
clearstatcache();
header('Content-Type: '.$type);
header("Content-Disposition: attachment; filename=".$filename);
header('Content-Length: ' . filesize($path));
readfile($path);
If you really want the processing to stop and didn't send any HTML content you can just use the header redirect:
header("Location: http://example.com/myOtherPage.php");
die();
If you already send content, you could use JavaScript to reload, but I can't give you an example without more context/code.
Related
I'm developing a web application.
A user can download a specific zip file using readfile() if the zip has been correctly generated.
But since I've integrated the readfile() line, I can't echo anything before or after this line. Here is the code sample causing problem :
if($zip->status == 0){
$zip->close();
$file_url = './zip/'.$userDir.'.zip';
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file_url) . "\"");
readfile($file_url);
echo'
<div class="alert alert-primary" role="alert">
Success
</div>';
}
Everything in the condition is called except for the echo lines at the end. When I remove the readfile($file_url) line, the echo is called.
I also tried to move the echo lines before the line
$file_url = './zip/'.$userDir.'.zip';
And it doesn't work either. Am I missing something ?
If you echo after "sending the file" to the user you are going to corrupt the file.
You have to think as the php code as a download link, the user clicks on it and get a file. Also sending an echo is not going to the user screen since you have this headers
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
I had a similar problem. In my case, a submitted form is generating a pdf file but since automatic download is initiated with readfile() on the action page, HTML of the latter wouldn't load, the browser keeps the form page open - that's where I added an overlay div which becomes visible only after clicking submit, blocking all content except a simple button which takes to the same action page but with the help of GET information, readfile() code isn't running again. Sure a button has to be clicked but it can be a good thing, some sort of download acknowledgement.
It feels, however, a bit odd, loading the same page twice.
I'm trying to redirect my user after they download my files. I manage to make them download the file but I cant redirect them to the url. Pleas help
<?php
//Search for file using GET
if(isset ($_GET['file']) && ($_GET['url'])){
$file = $_GET['file'];
$link = $_GET['url'];
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
} else {
echo "Why are you here?";
}
//file downloaded now go to link
header('Location: $link');
}
?>
How do I fix this?
No, it's not possible what you do and want.
your redirect will be executed if the GET parameters file and url exist and the physic file not exists.
if GET parameters file and url exist and the physic file exists, you exit after the download (script stops with further execution).
Why not a redirect from html code to your download script. Many downloads site work with.
As pseudo, redirect.html:
html
head
redirect to your forced download file FOO after X seconds with e.g. meta tag
/head
body
Download of file FOO starts in X seconds
/body
/html
In the case above you don't need the php redirect, only the force download. Set the redirect script not in the same file as your download script!
remove exit; from true part and try to put this instead
header('Location: $link');
You got the wrong quotes:
header("Location: $link"); // note the "
Or do concatenation:
header('Location: '.$link);
By the way, the way you're doing what you want to do is basically a good way to let anyone with HTTP 80 access to this script to download any file on your server. What if $file = '/etc/passwd';?
I have this code on http://domain.com/download.php
<?php
$remote_direct_link = "http://example.com/path/to/movie.mp4";
$filename = "movie-test.mp4";
$ctype="application/octet-stream";
header("HTTP/1.0 302 Found");
header("Content-Type: ".$ctype);
header("Connection: close");
header("Content-Disposition: attachment; filename=\"".basename($filename).'"');
header("Location: " . $remote_direct_link);
?>
When i access domain.com/download.php on browser, i want it to be forced downloaded file movie-test.mp4 with dialog on browser. But unfortunately, it always redirect to http://example.com/path/to/movie.mp4 and play it on browser. How can it do it ? Is there something wrong on my code.
Thanks
First of all, it seems like a really bad idea to download a file from a remote destination and then send it to the client. It gives a lot of overhead data transfer. The client has to wait till you downloaded the file, before you can serve it. Large files take a long time. Also, you have a new issue if the remote destination is unreachable.
That being said, you should pass the contents of the file, instead of redirecting.
<?php
$remote_direct_link = "http://example.com/path/to/movie.mp4";
$filename = "movie-test.mp4";
$ctype="application/octet-stream";
header("HTTP/1.0 302 Found");
header("Content-Type: ".$ctype);
header("Connection: close");
header("Content-Disposition: attachment; filename=\"".basename($filename).'"');
echo file_get_contents($remote_direct_link); // instead of redirection
?>
But a better and simpler approach would simply be having the file locally. It enables you to serve the file faster and you save half of the data transfer.
<?php
$file_contents = file_get_contents('../outside_http/movie.mp4');
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"movie-test.mp4\"");
echo $file_contents;
The last line in your code redirects the user to the external URL, which causes all your other code to be ignored. Instead, you may want to try using readfile() function like;
readfile($remote_direct_link);
I'm building a PHP application, one section of which will export an Excel file when a user submits the last of three pages of HTML forms. This takes a while to process, so on form submit I'm bringing up a "Please Wait" popup with JavaScript prior to processing beginning. The file is then created and downloaded on the users machine by setting the headers below
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $fileName . '.xls' .'"');
header('Cache-Control: max-age=0');
The problem I'm having, is that I then need to redirect the user back to the first page of the form. I can't echo a javascript location.href call, as the content-type has already been changed before this, so it never makes it to screen. Neither can I use a standard PHP header('Location: x') redirect for the same reason.
My question is, after diverting output to a file in the way above, how can I then either get the output back to screen to echo a JavaScript redirect, or redirect the user to a new page in some other way?
As always, any help is much appreciated.
James
Try this code
<?php
echo "<script>
window.location='page.php';
</script>";
?>
As described above there's no way to send new headers after the page has loaded, but there is a way to get the functionality I wanted.
The answer was to create an AJAX call, running in a setInterval loop which looks for a $_SESSION variable in the PHP. This session variable is set after the Excel file is created (where I was previously trying to place the redirect), causing the AJAX function to return success, and then perform a location.href redirect to the correct page.
the below code can do it. it can redirect you last page from where the download request is sent no need to echo content only readfile can do it so the page will automatically unload after download box appear.
$path is the path of your file to make user download
header("Content-type: application/vnd.ms-excel");
header('Content-Disposition: attachment; filename="'.$path.'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header("Cache-Control: public");
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($path));
readfile($path);
I need to retrieve our reports from the jasperserver report engine as a PDF, then I want the PDF to be forced as a download, instead of being displayed inthe browser. The problem with displaying in the browser is we don't want the report parameters to be displayed to the end users in the url.
If I enter this URL path into the browser I get a PDF document that shows in the same browser window with all the report data:
https://mysite.com:8443/jasperserver/flow.html?_flowId=viewReportFlow&reportUnit=sample_report&output=pdf;
What I would prefer to have happen is for a download dialog box to be used and for the users to download the PDF to their computer, instead of it showing in the browser.
I've tried the following php code, but can't get it to work. I get a return value of false, but nothing in the server logs that shows an error.
ob_start();
header("Location: $src"); /* Redirect browser */
$report_contents = ob_get_contents();
ob_end_clean();
var_dump($report_contents);
I'm not really sure how to go about this...anyone got any ideas?
Thanks for the help.
You could buffer the file to the PHP server then output with force download:
header('Content-disposition: attachment; filename=huge_document.pdf');
header('Content-type: application/pdf');
readfile('https://mysite.com:8443/jasperserver/flow.html?_flowId=viewReportFlow&reportUnit=sample_report&output=pdf;');
See the notes about using readfile over an HTTP stream wrapper
http://php.net/manual/en/function.readfile.php
how about
$source=$url
header("Expires: 0");
header("Cache-Control: private");
header("Pragma: cache");
header("Content-length: $size");
header("Content-type: $type");
header("Content-Disposition: attachment; filename=$name");
readfile($source);
exit();