How to force a file to download in PHP - php

I have list of images and I want a "Download" link along with every image so that user can download the image.
so can someone guide me How to Provide Download link for any file in php?
EDIT
I want a download panel to be displayed on clicking the download link I dont want to navigate to image to be displayed on the browser

If you want to force a download, you can use something like the following:
<?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.');
}
?>
If you simply link to this script using a normal link the file will be downloaded.
Incidentally, the code snippet above needs to be executed at the start of a page (before any headers or HTML output had occurred.) Also take care if you decide to create a function based around this for downloading arbitrary files - you'll need to ensure that you prevent directory traversal (realpath is handy), only permit downloads from within a defined area, etc. if you're accepting input from a $_GET or $_POST.

In HTML5 download attribute of <a> tag can be used:
echo '<a href="path/to/file" download>Download</a>';
This attribute is only used if the href attribute is set.
There are no restrictions on allowed values, and the browser will
automatically detect the correct file extension and add it to the file
(.img, .pdf, .txt, .html, etc.).
Read more here.

The solution is easier that you think ;) Simple use:
header('Content-Disposition: attachment');
And that's all. Facebook for example does the same.

You can do this in .htaccess and specify for different file extensions. It's sometimes easier to do this than hard-coding into the application.
<FilesMatch "\.(?i:pdf)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
By the way, you might need to clear browser cache before it works correctly.

Related

Creating simple button for .mp3 file download (no right-click, no media player)

I'm sure this is a simple task, but on my wordpress site I want to create a download button that forces an .mp3 download, without opening a player (when left clicked), or the user having to right-click 'save target as'. I just need a straight forward button, that when left-clicked causes a file to be downloaded (as well as being easily trackable by Google Analytics).
Is a .php script required for this? You'd think this would be a very common function, and easy to solve....but I have spent hours on this and have been unable to get anything to work.
*if it's not obvious my coding skills are nearly non-existent.
I really appreciate anybody's time who can help me figure this out. Thanks!
***EDIT
Just found this on another post, but no comments if it would work or not. It was for a .pdf file though...
<?php
if (isset($_GET['file'])) {
$file = $_GET['file'] ;
if (file_exists($file) && is_readable($file) && preg_match('/\.pdf$/',$file)) {
header('Content-type: application/pdf');
header("Content-Disposition: attachment; filename=\"$file\"");
readfile($file);
}
} else {
header("HTTP/1.0 404 Not Found");
echo "<h1>Error 404: File Not Found: <br /><em>$file</em></h1>";
}
?>
Save the above as download.php
Save this little snippet as a PHP file somewhere on your server and you can use it to make a file download in the browser, rather than display directly. If you want to serve files other than PDF, remove or edit line 5.
You can use it like so:
Add the following link to your HTML file.
Download the cool PDF.
Well, this is possible, but you need to write a script to do it. This is a pretty poor (security and basic coding wise) from http://youngdigitalgroup.com.au/tutorial-force-download-mp3-file-streaming/
file: downloadit.php
<?php
header ("Content-type: octet/stream");
header ("Content-disposition: attachment; filename=".$file.";");
header ("Content-Length: ".filesize($file));
readfile($file);
exit;
?>
you would then place it into a publicly accessible folder and build your links as such:
http://www.yoursite.com/downloadit.php?file=/uploads/dir/file.mp3
what this does is tells the browser to treat the file as a stream of bytes, rather than a particular MIME type which the browser would ordinarily do based on the file extension.

Link to a PDF in html, the file has no extension, but I know it is pdf how to make it open appropriately

First post. I'm working on a project for a client where they have pdf files uploaded to a file structure (LAMP Stack) but the files have no extensions on them. Under the assumption that those files have to be PDF how would I get the browsers to understand that, and open them accordingly? Obviously with adding the file extensions this would suddenly work but I can't change the way their system works, it would result in too many changes and they are on a tight deadline. As for saving a temporary copy somewhere, I could do that, but I was hoping for a better solution. Is there a way to suggest to the browsers that they open a file a certain way?
Any thoughts guys/gals?
You just set the application type and file name in the headers, like so:
// This points to the file in question, note that it doesn't
// care whether it has an extension on the name or not.
$filePathOnDisk = '/path/to/your/pdffile';
// You can make this whatever you like, it doesn't have to
// be the same as the file name on the disk! This is the name of the file your end
// user will see when they are asked if they want to save. open, etc in the browser.
$fileName = 'file.pdf';
$data = file_get_contents($filePathOnDisk);
header("Content-type: application/pdf");
header("Content-disposition: attachment;filename=$fileName");
echo $data;
See PHP: stream remote pdf to client browser and Proper MIME media type for PDF files for reference as well.
Tested
You can use the following which will prompt the user to save the (PDF) file on their computer.
Notice the different file names.
One is the file that will be uploaded/prompted to the user download_example.pdf, while the other is the file without an extension as set in readfile('example');
<?php
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="download_example.pdf"');
readfile('example');
?>

'Save As' image with src from PHP

I'm currently displaying images and hiding the src code by having a php file output the image. But when I right click on the image displayed and go down to 'Save As' it prompts me to download the php file not the actual image (obviously because it points to that src).
What can I do to download the actual image instead of displayImage.php?
It doesn't prompt you to download the PHP file, it simply uses that as the file name, because that is the file name from which it got the image data. If you manually input a valid image file name and try to open what you saved, it should still be a valid image.
You may also be able to give it a sensible name by including the file name in a Content-Disposition: header from your PHP file, e.g.
$filename = 'image.jpg';
header('Content-Disposition: inline; filename="'.$filename.'"');
// Don't forget the Content-Type as well...
// Output image here
...however this relies on the browser handling this sensibly, which not all of them do :-(
You can send a filename in the header.
header("Content-Type: image/png");
header('Content-Disposition: inline; filename="some.png"');
Send the correct content type in the image generator script:
header('Content-type: image/jpg');
If you want to have the .jpg extension when a PHP script is outputting an image, you'll need to do a htaccess or httpd.conf rewrite, where you can rewrite a .jpg request, to your php image generator script.
See mod_rewrite http://httpd.apache.org/docs/current/mod/mod_rewrite.html

Is there a way to force the user to download a file from a href link rather than to open it in a browser window?

Basically I wrote a script that generates a xml file based on user input. After the file is generated a download link appears like so:
Download File
But when clicked it opens the xml in the browser, I want it to start downloading when the link it clicked instead. Is there any way to achieve that?
Yeah, there is. It does require specifying some headers. Exactly how it works depends on what language you're using, but here's an example using php, taken off of php.net:
<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');
// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');
// The PDF source is in original.pdf
readfile('original.pdf');
?>
Basically, first we tell the client what type of file we're sending, then we tell the client that what we're sending is an attachment, and it's name, instead of it being a page to display, and then finally we print/read the file to the output.
Given that you're already using php to generate the xml file, I would suggest adding the header commands above to the code that generates the xml file, and see if that does the trick.
If you happen to be using Apache for your web server, and you always want to force downloading of XML files, there is a more efficient way to do what #chigley suggested. Just add the following to a .htaccess file.
<Files *.xml>
ForceType application/xml
Header set Content-Disposition attachment
</Files>
What happens when a browser sees a link is not dependent on the link, but rather on the target of the link. Your web server should send the appropriate header: Content-Disposition: attachment;filename="file.xml" to tell the browser that it should prompt to save the file instead of displaying it.
It depends on what the client computer does with XML files. If you doubleclick on a XML file, it will open in your browser probably.
download.php:
header('Content-Type: text/xml');
header('Content-Disposition: attachment; filename="file.xml"');
readfile('/path/to/file.xml');
HTML:
Download

How can I force a Save-As dialog box without leaving the page in php?

I have an anchor tag:
Download Me
I would like for the user to click on it and then have a Save-As dialog box appear with a new filename I determine.
I found this(http://www.w3schools.com/php/func_http_header.asp):
header("Content-type:application/pdf");
// It will be called downloaded.pdf
header("Content-Disposition:attachment;filename='downloaded.pdf'");
// The PDF source is in file.pdf
readfile("file.pdf");
I don't understand where to put those headers. At the top of the page? When I try to place those 3 lines directly above my link I receive the following errors:
Warning: Cannot modify header
information - headers already sent by
(output started at
/home5/ideapale/public_html/amatorders_basic/admin/download.php:38)
in
/home5/ideapale/public_html/amatorders_basic/admin/download.php
on line 118
I got the same error for both of the header lines I just added. Right after that, there are thousands lines of ASCII letters. How can I get the Save-As dialog box to appear using either jQuery or PHP(whatever is easier)?
Please be careful when using Stijn Van Bael's code, it opens you up to some serious security exploits.
Try something like:
--- download.php ---
$allowed_files = array('file.pdf', 'otherfile.pdf');
if (isset($_REQUEST['file']) && in_array($_REQUEST['file'], $allowed_files))
{
$filename = $_REQUEST['file'];
header("Content-type:application/pdf");
header("Content-Disposition:attachment;filename='$filename'");
// The PDF source is in file.pdf
readfile($filename);
exit();
}
else
{
// error
}
--- linkpage.php ---
Download PDF
Download PDF
Probabaly a better way to do this is at the web server level (this can go in .htaccess) This will force all PDF's to be treated as a binary file (forcing the browser to download them) in and below the directory you put this in.
<FilesMatch "\.(?i:pdf)$">
Header set Content-Disposition attachment
ForceType application/octet-stream
</FilesMatch>
Create a new page with the headers and the readfile, then make the download link refer to the page, which will return the PDF file.
For example:
Download Me
Source for download.php:
$filename = $_REQUEST['file'];
header("Content-type:application/pdf");
// It will be called downloaded.pdf
header("Content-Disposition:attachment;filename='$filename'");
// The PDF source is in file.pdf
readfile($filename);
Or you could just use the new HTML5 property download in the anchor tag of your html.
The code will look something like
<a download href="path/to/the/download/file"> Clicking on this link will force download the file</a>

Categories