This question already has answers here:
Handle file download from ajax post
(21 answers)
Closed last year.
I am new to php and ajax. Im trying to force download a file from a list of documents. The functions below gets triggered using an ajax call after a button click.
function downloadDocument($filename) {
$file_path = ".........../DocUploader/Uploads/" . $filename;
if (file_exists($file_path)) {
header("Content-Description: File Transfer");
header("Content-Type: application/json");
header("Content-Disposition: attachment; filename=\'" . $filename);
readfile($file_path);
} else{
echo "Document does not exist";
}};
Instead of downloading the file, I assume I am getting the file content as a response. I would really appreciate any advise on what I should do.
First remove any echo's or output to the browser before sending any header, ie. remove the echo "File exists";
The file name should be encapsulated in quotations, ie. Content-Disposition: attachment; filename="filename.ext"
<?php
header("Content-Description: File Transfer");
header("Content-Type: application/json");
header('Content-Disposition: attachment; filename="'. $filename .'"');
readfile($file_path);
Keep in mind to set correct Content-type based on the real kind of the downloaded document, see topic What are all the possible values for HTTP "Content-Type" header?
You can dynamically detect the MIME type using PHP function mime_content_type()
And reference for PHP header.
Related
I'm learning PHP so this is the question for education purposes. Since I can't find an answer in tutorials I use, would be nice from you to make it clear for me.
So, imagine we have a file "text.txt" and content is:
"Hello World!"
The following PHP script:
<?php
echo readfile("text.txt");
?>
Will output "Hello World!12" - I can't think of any cases when such an output can be useful, but I found that if I don't want to see the file length at the end, I've to omit "echo":
<?php
readfile("text.txt");
?>
The output will be "Hello World!". This is a way better, but manual says: "Returns the number of bytes read from the file.", so my question is - How am I supposed to get the file length using the readfile() function? According to my logic it "returns" the file content but I feel like I didn't get something right. Please help me to figure this out.
So you want to read the size of a file using readfile()? Sure, but this function also outputs the file. No biggie, we have something we can use in this situation: output buffering.
<?php
ob_start();
$length = readfile("text.txt");
// the content of the file isn't lost as well, and you can manipulate it
$content = ob_get_clean();
echo $length;
?>
readfile is not used to get file size or file content the way you write. It is typically used to send a file to the client. For example, suppose that you have created a pdf file in your web application after the client submit a form or clicked some link. Sometimes you can direct them to the file directly, but sometimes you dont want that for some reasons(security etc.). This way you can do this:
How it is ment to be used.
$filepath = "../files/test.pdf";
header("Content-Description: File Transfer");
header("Content-Type: application/pdf; charset=UTF-8");
header("Content-Disposition: inline; filename='test.pdf'");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($filepath));
readfile($filepath);
exit;
An example for which you may use it.
$filepath = "../files/test.pdf";
ob_start();
$filesize = readfile($filepath);
$content = ob_get_clean();
header("Content-Description: File Transfer");
header("Content-Type: application/pdf; charset=UTF-8");
header("Content-Disposition: inline; filename='test.pdf'");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $filesize );
echo $content;
exit;
So, here you output the file content in addition to the correct headers so that the browser will identify it as a pdf file and open it.
I use header() to download an xlsx file from given url. The file is downloaded but I can't not open it. It shows error
Below is my code
$url = "http://example.com/attachment/file.xlsx"
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header('Content-Disposition: attachment; filename=Test.xlsx');
readfile($url);
exit();
Randy, your question looks weird. The URL in the serve response is way different than the one in your code.
Before commencing the download - sending the headers, do a is_file() or other check on the URL and only start the download if the file exists.
I suspect you are trying fopen on URL, not local file and the URL may be either incorrect or on server not allowing fopen on URLs.
Sample:
$url = "http://example.com/attachment/file.xlsx";
if (!fopen($url,'r')) exit('File/URL not accessible');
else fclose($url);
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header('Content-Disposition: attachment; filename=Test.xlsx');
readfile($url);
exit();
This question already has answers here:
How to download a php file without executing it?
(6 answers)
Closed 7 years ago.
I have a website, and I want to be able to put a link that enables the user to download a php file, I don't want it to run or for the user to navigate to the url, but be able to download the original file, is this possible?
Thanks
Thanks Biswajit, that link got me what I needed (I saw the original "duplicate" but I wasn't working for me)
<?php
// Fetch the file info.
$filePath = '/path/to/file/on/disk.jpg';
if(file_exists($filePath)) {
$fileName = basename($filePath);
$fileSize = filesize($filePath);
// Output headers.
header("Cache-Control: private");
header("Content-Type: application/stream");
header("Content-Length: ".$fileSize);
header("Content-Disposition: attachment; filename=".$fileName);
// Output file.
readfile ($filePath);
exit();
}
else {
die('The provided file path is not valid.');
}
?>
Here's what I'm trying to do. I have a series of reports that they also want to be able to download as comma delimited text files. I've read over a bunch of pages where people say simply echo out the results rather than creating a file, but when I try that it just outputs to the page they are on.
I have this in the form of each report
Export File<input type="checkbox" name="export" value="1" />
So on the post I can check if they are trying to export the file. If they are I was trying to do this:
if($_POST['export'] == '1')
{
$filename = date("Instructors by DOB - ".$month) . '.txt';
$content = "";
# Titlte of the CSV
$content = "Name,Address,City,State,Zip,DOB\n";
for($i=0;$i<count($instructors);$i++)
$content .= ""; //fill content
fwrite($filename, $content);
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Length: ". filesize("$filename").";");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Type: application/octet-stream; ");
header("Content-Transfer-Encoding: binary");
readfile($filename);
}
Basically the page refreshes, but no file is pushed for download. Can anyone point out what I'm missing?
EDIT
I think I wasn't entirely clear. This is not on a page that only creates and downloads the file, this is on a page that is also displaying the report. So when I put an exit(); after the readfile the rest of the page loads blank. I need to display the report on this page as well. I think this could also have to do with why it's not download, because this page has already sent header information.
I overlooked the way you are writing out the contents before asking you to try closing the file.
Check the fwrite manual here: http://php.net/manual/en/function.fwrite.php
What you need to do is:
$filename = "yourfile.txt";
#...
$f = fopen($filename, 'w');
fwrite($f, $content);
fclose($f);
and after closing the file, you can now safely send it across for download.
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Length: ". filesize("$filename").";");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Type: application/octet-stream; ");
header("Content-Transfer-Encoding: binary");
readfile($filename);
There are a couple of things:
You really dont need to set the content-type as application/octet-stream. Why not set a more real type as text/plain?
I really dont understand how you want to use the date functionality. please refer to the manual here: http://php.net/manual/en/function.date.php
As correctly pointed out by #nickb, you must exit the script after doing the readfile(..)
This question already has answers here:
php - How to force download of a file?
(7 answers)
Closed 7 years ago.
I have a php page with information, and links to files, such as pdf files. The file types can be anything, as they can be uploaded by a user.
I would like to know how to force a download for any type of file, without forcing a download of links to other pages linked from the site. I know it's possible to do this with headers, but I don't want to break the rest of my site.
All the links to other pages are done via Javascript, and the actual link is to #, so maybe this would be OK?
Should I just set
header('Content-Disposition: attachment;)
for the entire page?
You need to send these two header fields for the particular resources:
Content-Type: application/octet-stream
Content-Disposition: attachment
The Content-Disposition can additionally have a filename parameter.
You can do this either by using a PHP script that sends the files:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment');
readfile($fileToSend);
exit;
And the filenames are passed to that script via URL. Or you use some web server features such as mod_rewrite to force the type:
RewriteEngine on
RewriteRule ^download/ - [L,T=application/octet-stream]
Slightly different style and ready to go :)
$file = 'folder/' . $name;
if (! file) {
die('file not found'); //Or do something
} else {
// Set headers
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$file");
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: binary");
// Read the file from disk
readfile($file);
}